使用下拉列表 [react hooks] 更改状态后,不会重新呈现 React 组件

React component is not re-rendered after the state is changed with a dropdown list [react hooks]

我有以下 React 组件(使用 hooks),它列出了一些 Tasks 作为下拉列表。当从列表中 selected 一个项目时,我想显示一个 Update 表单。这仅在项目首次 selected 时有效。当我 select 一个新项目时,没有任何反应(尽管 console.log(e.target.value); 打印出正确的值)。我将 selected 任务的 ID 存储在 st_taskId.

不知道您是否发现以下代码有任何问题:

const ManageReviewTasks = props => {
  const reviewRoundId = props.match.params.reviewRoundId;
  const [st_taskId, set_taskId] = useState();

  useEffect(() => {
    if (props.loading == false && st_taskId == null)
      props.fetchReviewTasksByReviewRound(reviewRoundId);
  }, [reviewRoundId, st_taskId]);

  if (props.loading == true) {
    return <div>Loading...</div>;
  }

  return (
    <>
      {props.reviewTasks && (
        <div>
          <h3>Configure the Review Tasks</h3>
          <br />
          {
            <div>
              <div>
                <h4>
                  Tasks for <span className="font-italic">students receiving</span> feedback:
                </h4>
                <select
                  className="form-control"
                  onChange={e => {
                    e.preventDefault();
                    console.log(e.target.value);
                    set_taskId(e.target.value);
                  }}>
                  <option>--SELECT--</option>
                  {Object.keys(props.reviewTasks).map(id => {
                    const task = props.reviewTasks[id];
                    {
                      if (task.isForStudent) {
                        return (
                          <option key={id} id={id} value={id}>
                            {task.title}
                          </option>
                        );
                      }
                    }
                  })}
                </select>
              </div>
              {props.reviewTasks[st_taskId] && (
                <UpdateReviewTaskForm task={props.reviewTasks[st_taskId]} />
              )}
            </div>
          }
        </div>
      )}
    </>
  );
};

下面是 UpdateReviewTaskForm 组件的代码:

const UpdateReviewTaskForm = (props) => {

    const [st_Title, set_Title] = useState(props.task.title);
    const [st_Description, set_Description] = useState(RichTextEditor.createValueFromString(props.task.description, 'html'));
    const [st_startDate, set_startDate] = useState(new Date(props.task.startDate.replace('-', '/')));
    const [st_DueDate, set_DueDate] = useState(new Date(props.task.dueDate.replace('-', '/')));



    const handleCancelClick = (event) => {
        event.preventDefault();
        history.goBack();
    }

    const onSubmit_saveTask = (e) => {
        e.preventDefault();

        props.updateReviewTask({
            Id: props.task.id,
            Title: st_Title,
            Description: st_Description.toString('html'),
            StartDate: format(st_startDate, 'DD/MM/YYYY'),
            DueDate: format(st_DueDate, 'DD/MM/YYYY'),
        })
    }

    if (props.loading) 
        return <div>Updating...</div>

    return (
        <div>
            <br/>
            <br/>
            <div className="p-3 bg-light">
                <h3 className="text-info">Update the Task:</h3>
                {
                    props.task &&
                    <form onSubmit={onSubmit_saveTask}>
                        <div className="form-group">
                            <label>Enter the title</label>
                            <input
                                //placeholder="Enter a title..."
                                value={st_Title}
                                onChange={(event) => { set_Title(event.target.value) }}
                                className="form-control" />
                        </div>

                        <div className="form-group">
                            <label>Enter a description for the assessment</label>
                            <RichTextEditor
                                value={st_Description}
                                onChange={set_Description}
                            />
                        </div>

                        <div className="form-group">
                            <label>Start date to start:&nbsp;</label>
                            <DatePicker
                                className="form-control"
                                selected={st_startDate}
                                onChange={(date) => set_startDate(date)}
                            />
                        </div>
                        <div className="form-group">
                            <label>Due date to complete:&nbsp;</label>
                            <DatePicker
                                className="form-control"
                                selected={st_DueDate}
                                onChange={(date) => set_DueDate(date)}
                            />
                        </div>

                        <br />
                        <button type="submit" className="btn btn-primary">Submit</button>&nbsp;
                        <button type="reset" className="btn btn-light" onClick={handleCancelClick}>Cancel</button>
                    </form>
                }
            </div>
        </div>
    )
}

因为你在UpdateReviewTaskForm中使用了内部状态,即使这个组件第二次重新渲染,它的状态也不会被重置(例如到默认值props.task.title)。

强制状态重置的一种方法是在 UpdateReviewTaskForm 中使用 key 道具,如下所示:

  {props.reviewTasks[st_taskId] && (
    <UpdateReviewTaskForm key={st_taskId} task={props.reviewTasks[st_taskId]} />
  )}

另一种方法是在 UpdateReviewTaskForm 中使用 useEffect 到 运行 当 props.task 更改

useEffect(() => {
// reset the state here
}, [props.task])