Почему моя страница перезагружается после обновления триггера onChange?

#javascript #reactjs

#javascript #reactjs

Вопрос:

Я добавил разные формы в разные методы, но когда я ввожу что-либо в поля ввода, страница перезагружается с сохранением состояний, и снова я должен щелкнуть по полю и ввести, и происходит тот же цикл. Он работает нормально, если я добавляю все взамен. Может кто-нибудь объяснить, почему это происходит и как это остановить? Я также делюсь фрагментом кода.

 function MyForm() {
    const [commentForm, setCommentForm] = useState({
        Comment: "",
    });

    const onCommentChange = (obj) => {
        setCommentForm((prevState) => {
            return {
                ...prevState,
                ...obj,
            };
        });
    };

    const IForm = () => (

        <Table>
            <CardBody>
                <Row>
                    <Col className="col-2">
                        <Label>Comment: </Label>
                    </Col>
                    <Col className="col-1">
                        <Input type="text"
                            value={commentForm.Comment}
                            onChange={(e) =>
                                onCommentChange({ Comment: e.target.value })} />
                    </Col>
                </Row>
            </CardBody>
        </Table>
    );
    return (
        <div>
            <IForm />
        </div>
    )
}
export default MyForm
 

Комментарии:

1. e.target.value это строка, а не объект; нет смысла ее распространять ... . Что вы setCommentForm() должны вернуть ...prevState, Comment: obj (я предполагаю, что у вас есть свои причины устанавливать и обрабатывать состояние так, как вы это делали, хотя ваш пример кода предполагает, что вы могли бы сделать это гораздо более простым способом)

Ответ №1:

это потому, что вы определяете IForm как компонент внутри текущего компонента, что неверно. итак, у вас есть два решения.

1 — переместитесь IFORM Component за пределы текущей реакции.

 function MyForm() {
  const [commentForm, setCommentForm] = React.useState({
    Comment: ""
  });

  const onCommentChange = (obj) => {
    setCommentForm((prevState) => {
      return {
        ...prevState,
        ...obj
      };
    });
  };

  return (
    <div>
      <IForm commentForm={commentForm} onCommentChange={onCommentChange} />
    </div>
  );
}
export default MyForm;

const IForm = ({ commentForm, onCommentChange }) => (
  <Table>
        <CardBody>
            <Row>
                <Col className="col-2">
                    <Label>Comment: </Label>
                </Col>
                <Col className="col-1">
                    <Input type="text"
                        value={commentForm.Comment}
                        onChange={(e) =>
                        onCommentChange({ Comment: e.target.value })} />
                </Col>
            </Row>
        </CardBody>
  </Table>
);
 

2 . объявите IForm как обычную функцию внутри текущего компонента.

 function MyForm() {
  const [commentForm, setCommentForm] = React.useState({
    Comment: ""
  });

  const onCommentChange = (obj) => {
    setCommentForm((prevState) => {
      return {
        ...prevState,
        ...obj
      };
    });
  };

  const form = () => (
    <Table>
        <CardBody>
            <Row>
                <Col className="col-2">
                    <Label>Comment: </Label>
                </Col>
                <Col className="col-1">
                    <Input type="text"
                        value={commentForm.Comment}
                        onChange={(e) =>
                            onCommentChange({ Comment: e.target.value })} />
                </Col>
            </Row>
        </CardBody>
    </Table>
  );

  return <div> {form()} </div>;
}
export default MyForm;
 

Комментарии:

1. Есть ли другой способ? Потому что существует 1000 строк кода, и для изменения потребуется много времени.

Ответ №2:

Причина в том, что компонент IForm объявлен внутри компонента MyForm. Это означает, что всякий раз, когда изменяется состояние компонента MyForm, он обновляет свое дерево dom. И когда dom повторно отобразит функциональный компонент, IForm будет выполняться снова, поэтому вы всегда будете терять фокус ввода, но вы никогда не теряете состояние компонента MyForm.

Чтобы остановить это, либо объявите компонент IForm вне компонента MyForm, либо переместите jsx IForm внутри возвращаемого компонента MyFOrm.

Ответ №3:

Вы должны просто setCommentForm указать значение. Я не думаю, что вам нужно распространять prevState.

Чего вы хотите добиться, так это установить значение состояния на новое.

Кроме того, у вас нет никаких useEffect прав?

Комментарии:

1. Зачем в этом нужен useEffect?

2. Нет, вот почему я спрашивал, использовали ли вы его где-нибудь. Вы решили это? (:

3. Я получил свой ответ. В любом случае спасибо за помощь. 🙂