在React中清除父组件和子组件之间的状态和输入值

时间:2019-03-04 20:47:44

标签: javascript reactjs input state

这里有两个部分的问题:首先,有人可以向我解释为什么提交表单后未清除this.state.taskName和this.state.taskBody及其对应的输入吗?在handleSubmit()中,我正在使用this.setState()将其状态设置为空字符串,但似乎无法正常工作。这也不会让我多次提交,我怀疑这可能与国家未清算有关。

第二,将具有多个键值对的任务推入this.state.tasks数组的最佳方法是什么?我尝试将taskName和taskBody存储为状态对象,还尝试将它们推入对象然后显示它们,但是无法正常工作。

以下是父,子和同级文件:

import React, { Component } from 'react';
import Task from './Task/Task';
import NewTaskForm from './NewTaskForm/NewTaskForm';

class Board extends Component {
    constructor(props) {
        super(props);

        this.handleSubmit = this.handleSubmit.bind(this);
        this.handleChange = this.handleChange.bind(this);

        this.state = {
            tasks: [],
            taskName: '',
            taskBody: ''
        };
    }

    handleSubmit(e) {
        e.preventDefault();
        let updatedTasks = this.state.tasks;
        let taskName = this.state.taskName;
        let taskBody = this.state.taskBody;

        updatedTasks.push(taskName, taskBody);
        let updatedName = '';
        let updatedBody = '';
        this.setState({ tasks: updatedTasks, taskName: updatedName, taskBody: updatedBody });
    };

    handleChange(e) {
        this.setState({ [e.name]: e.value });
    }

    render() {
        return (
            <div>
                <NewTaskForm
                    onSubmit={this.handleSubmit}
                    onChange={this.handleChange}
                />
                <Task
                    tasks={this.state.tasks}
                />
            </div>
        );
    }
}

export default Board;


import React, { Component } from 'react';

class NewTaskForm extends Component {
    constructor(props) {
        super(props);

        this.handleChange = this.handleChange.bind(this);
    }

    handleChange(e) {
        this.props.onChange(e.target);
    }

    render() {
        return (
            <form onSubmit={this.props.onSubmit}>
                <label>Task Name</label>
                <input
                    name="taskName"
                    required type="text"
                    value={this.props.taskName}
                    onChange={this.handleChange}
                    placeholder="Enter a task name"
                />

                <label>Task Body</label>
                <input
                    name="taskBody"
                    required type="text"
                    value={this.props.taskBody}
                    onChange={this.handleChange}
                    placeholder="Enter a task body"
                />

                <button
                    type="submit"
                    className="btn btn-default"
                >Add Task
                </button>
            </form>
        );
    }
}

export default NewTaskForm;


import React, { Component } from 'react';

class Task extends Component {
    render() {
        let taskList = this.props.tasks.map((task, i) => {
            return (
                <li key={i}>
                    {task}
                </li>
            );
        });
        return (
            <ul>
                {taskList}
            </ul>
        )
    }
}

export default Task;

谢谢!

4 个答案:

答案 0 :(得分:3)

要解决第一个问题,未清除输入的原因是因为您没有将taskNametaskBody值作为对<NewTaskForm />的支持。由于NewTaskForm未接收到输入,因此它们不受React的控制,因此它们目前完全由用户控制。添加它们,您将在提交表单后看到它们。

taskName / taskBody对保持在状态的最佳方法是您所说的:一个对象。不过,在TaskComponent中,您需要更改映射逻辑以与对象一起使用,并确保将对象推入this.state.tasks中的Board。我已链接到显示我所做更改的小提琴:https://jsfiddle.net/0z89Lcpw/

具体来说,我对您的代码所做的更改是:

  • 修改了第21行以推送形状为{taskName, taskBody}的对象
  • 在第37和38行中添加了taskNametaskBody道具传递给NewTaskForm
  • 更改了第95行(旧的:第93行)以将taskNametaskBody从每个任务中拉出并同时显示两者-当然,您可以用多种不同的方式显示这些数据,适合您的演示目的。

答案 1 :(得分:1)

我看到您编写代码的方式有几个问题。对于初学者,您不会将taskNametaskBody作为道具传递给NewTaskForm,因为组件希望从道具中读取值。

  • 改变状态不是一个好主意
  • 由于名称和身体包含在任务中,因此要保持形状。

检查此代码段-https://codesandbox.io/s/ov675m6r7y

答案 2 :(得分:1)

请在下面查看您更改的代码。我在下面添加了对我所做的主要更改的说明:)

class Board extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      tasks: [],
      taskName: '',
      taskBody: ''
    };
  }

  handleSubmit(e) {
    e.preventDefault();

    let tasks = this.state.tasks;
    let taskName = this.state.taskName;
    let taskBody = this.state.taskBody;

    tasks.push({taskName, taskBody});

    this.setState({tasks, taskName: '', taskBody: ''});
  };

  handleChange(e) {
    const name = e.target.name; 
    const value = e.target.value;

    this.setState({[name]: value});
  }

  render() {
    return (
      <div>
        <NewTaskForm
          taskName={this.state.taskName}
          taskBody={this.state.taskBody}
          onSubmit={(e) => this.handleSubmit(e)}
          onChange={(e) => this.handleChange(e)}
        />
        <Tasks
          tasks={this.state.tasks}
        />
      </div>
    );
  }
}

class NewTaskForm extends React.Component {
  render() {
    return (
      <form onSubmit={this.props.onSubmit}>
        <label>Task Name</label>
        <input
          name="taskName"
          required type="text"
          value={this.props.taskName}
          onChange={(e) => this.props.onChange(e)}
          placeholder="Enter a task name"
        />

        <label>Task Body</label>
        <input
          name="taskBody"
          required type="text"
          value={this.props.taskBody}
          onChange={(e) => this.props.onChange(e)}
          placeholder="Enter a task body"
        />

        <button type="submit" className="btn btn-default">Add Task</button>
      </form>
    );
  }
}

class Tasks extends React.Component {
  render() {
    let taskList = this.props.tasks.map((task, i) => {
      return (
        <li key={i}>
          <b>{task.taskName}</b><br/>
          {task.taskBody}
        </li>
      );
    });

    return (
      <ul>
        {taskList}
      </ul>
    )
  }
}
  1. 通过taskName和taskBody作为对NewTaskForm的支持 要在其输入中使用的组件。
  2. 您将新任务错误地推到了更新后的任务列表中。
  3. 在“任务”组件中,您没有显示 任务,您正在尝试显示任务对象。

正在工作的小提琴:https://jsfiddle.net/8sLw4phf/2/

答案 3 :(得分:0)

我会尝试这样的事情:

handleSubmit(e) {
    e.preventDefault();
    const { taskName, taskBody } = this.state;
    this.setState({ 
        tasks: [...this.state.tasks, { taskName, taskBody }] 
        taskName: '', 
        taskBody: '' 
    });
};

这样,您就不会改变状态,并且每个任务的数组包含一个对象。