0

我有以下 React 组件(使用hooks),其中列出了一些Tasks作为下拉列表。当从列表中选择一个项目时,我想显示一个Update表单。这仅在第一次选择项目时有效。当我选择一个新项目时,什么也没有发生(尽管console.log(e.target.value);打印了正确的值)。我将所选任务的 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>
    )
}
4

1 回答 1

1

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

强制状态重置的一种方法是使用这样的key道具UpdateReviewTaskForm

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

另一种方法是在更改时使用useEffectinsideUpdateReviewTaskForm运行props.task

useEffect(() => {
// reset the state here
}, [props.task])
于 2019-09-11T09:15:47.653 回答