繁体   English   中英

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

[英]Clearing state and input values between parent and child components in React

这里有两个部分的问题:首先,有人可以向我解释为什么提交表单后未清除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;

谢谢!

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

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

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

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

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

  • 改变状态不是一个好主意
  • 正如名称和身体包含在任务中一样,请为其保持形状。

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

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

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/

我会尝试这样的事情:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM