使用事件侦听器时,状态保持不变



https://codesandbox.io/s/state-shenanigans-mifyg

这个代码示例有点不正统,但它仍然让我感到困惑,所以我决定把它变成一个问题。

请打开上面的链接并播放示例。同时使控制台保持打开状态。

当表单更改时,我正在调用 console.log,向其传递状态。正如您在更改问题时所看到的,它会记录正确的值(具有现有答案的新问题(。

但是,如果您随后更改答案,您会发现问题已与新答案一起注销。

我想这与闭包有关,但我无法弄清楚。

import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
function Faq({ onChange, data }) {
  const questionRef = React.createRef<HTMLInputElement>();
  const answerRef = React.createRef<HTMLInputElement>();
  React.useEffect(() => {
    if (questionRef.current) {
      questionRef.current.addEventListener("keydown", (e: any) => {
        onChange({ ...data, question: e.target.value });
      });
    }
    if (answerRef.current) {
      answerRef.current.addEventListener("keydown", (e: any) => {
        onChange({ ...data, answer: e.target.value });
      });
    }
  }, []);
  return (
    <div>
      <input ref={questionRef} type="text" defaultValue={data.question} />
      <input ref={answerRef} type="text" defaultValue={data.answer} />
    </div>
  );
}
const App = () => {
  const [faq, setFaq] = React.useState({
    id: "1",
    question: "I am a question?",
    answer: "I am the answer!"
  });
  React.useEffect(() => {
    console.log(faq);
  }, [faq]);
  return <Faq data={faq} onChange={setFaq} />;
};
const rootElement = document.getElementById("root");
render(<App />, rootElement);

我不确定你所说的"旧"和"新"问题是什么意思,因为只有一个问题。在任何情况下,您都不必在 React 中使用 DOM 引用和手动 EvenListeners。React 的发明是为了为你处理这种事情!

function Faq({ onChange, data }) {
  const handleChange = (e) => {
    console.log("the new value is")
    console.log(e.currentTarget.value)
  }
  return (
    <div>
      <input onChange={handleChange} type="text" defaultValue={data.question} />
      <input onChange={handleChange} type="text" defaultValue={data.answer} />
    </div>
  );
}

您需要刷新数据:

import * as React from "react";
import { render } from "react-dom";
import "./styles.css";
function Faq({ onChange, data }) {
  const questionRef = React.createRef<HTMLInputElement>();
  const answerRef = React.createRef<HTMLInputElement>();
  React.useEffect(() => {
    if (questionRef.current) {
      questionRef.current.addEventListener("keydown", (e: any) => {
        onChange({ ...data, question: e.target.value });
        data.question = e.target.value;
      });
    }
    if (answerRef.current) {
      answerRef.current.addEventListener("keydown", (e: any) => {
        onChange({ ...data, answer: e.target.value });
        data.answer = e.target.value;
      });
    }
  }, []);
  return (
    <div>
      <input ref={questionRef} type="text" defaultValue={data.question} />
      <input ref={answerRef} type="text" defaultValue={data.answer} />
    </div>
  );
}
const App = () => {
  const [faq, setFaq] = React.useState({
    id: "1",
    question: "I am a question?",
    answer: "I am the answer!"
  });
  React.useEffect(() => {
    console.log(faq);
  }, [faq]);
  return <Faq data={faq} onChange={setFaq} />;
};
const rootElement = document.getElementById("root");
render(<App />, rootElement);

https://codesandbox.io/s/state-shenanigans-kupjj

相关内容

  • 没有找到相关文章

最新更新