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