Очистка состояния и входных значений между родительским и дочерним компонентами в React - PullRequest
0 голосов
/ 04 марта 2019

Вопрос состоит из двух частей: во-первых, кто-нибудь может объяснить мне, почему this.state.taskName и this.state.taskBody и их соответствующие входные данные не очищаются после отправки формы?В handleSubmit () я использую this.setState (), чтобы установить их состояния в пустую строку, но это, похоже, не работает.Это также не позволит мне отправлять более одного раза, что, как я подозреваю, может иметь отношение к состоянию, не очищающему.

Во-вторых, что было бы лучшим способом вставить задачу с несколькими парами ключ-значение вмассив .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 голосов
/ 05 марта 2019

Пожалуйста, смотрите ваш измененный код ниже.Ниже я добавил объяснения для основных изменений, которые я сделал:)

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/

0 голосов
/ 05 марта 2019

Я бы попробовал что-то вроде этого:

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

Таким образом, вы не изменяете свое состояние, и ваш массив содержит один объект на задачу.

0 голосов
/ 05 марта 2019

Я вижу несколько проблем с тем, как вы написали код.Для начала, вы не передаете taskName и taskBody как реквизиты в NewTaskForm, так как компонент ожидает, что значение будет считано из реквизита.

  • Не очень хорошая идея изменять состояние
  • Поскольку имя и тело входят в задачу, сохраняйте форму для нее.

Проверьте этофрагмент кода - https://codesandbox.io/s/ov675m6r7y

0 голосов
/ 05 марта 2019

Чтобы ответить на ваш первый вопрос, причина, по которой входные данные не очищаются, заключается в том, что вы не передаете значения taskName и taskBody в качестве реквизитов для <NewTaskForm />.React не управляет входами, поскольку NewTaskForm не получает их, поэтому в настоящее время они полностью контролируются пользователем.Добавьте их, и вы увидите их чистыми после отправки формы.

Лучший способ удержать пару taskName / taskBody в состоянии, как вы сказали: объект.В вашем TaskComponent вам потребуется изменить логику отображения для работы с объектом, а также убедиться, что вы выдвигаете объект на this.state.tasks в Board.Я связался с Fiddle, который показывает сделанные мной изменения: https://jsfiddle.net/0z89Lcpw/.

В частности, изменения, которые я сделал по сравнению с вашим кодом:

  • измененная строка 21 для толкания объекта с помощьюshape {taskName, taskBody}
  • добавлены строки 37 и 38 для передачи taskName и taskBody для перехода на NewTaskForm
  • изменена строка 95 (старая: строка 93) для вытягивания taskName иtaskBody от каждой задачи и представляйте обе - конечно, вы можете представить эти фрагменты данных несколькими различными способами в соответствии с вашими презентационными целями.
...