https://codesandbox.io/s/state-shenanigans-mifyg
这个代码示例有点不合常规,但是仍然让我感到困惑,所以我决定将其变成一个问题。
请打开上面的链接,然后播放示例。保持控制台保持打开状态。
当表单更改时,我正在调用console.log,并将其传递给状态。如您所见,更改问题时,它会记录正确的值(带有现有答案的新问题)。
但是,如果您随后更改答案,则会发现 old 问题已与新答案一起注销。
我想它与闭包有关,但我无法弄清楚。
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);
答案 0 :(得分:0)
我不确定您所说的“旧”和“新”问题是什么意思,因为只有一个问题。无论如何,您都不必在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>
);
}
答案 1 :(得分:0)
您将需要刷新数据:
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);