React:设置useState()钩子是否清除输入字段



每当我在React应用程序中设置状态时,它都会清除我的输入(复选框、数字(。这里有一个非常简单的版本来说明这个问题。

import React, { useState } from "react";
export default function App() {
const [dummy, setDummy] = useState(false);
function handleMint() {
setDummy((dummy) => !dummy);
}
const MintBTN = () => (
<div>
<div>
<input className="form-control" type="number" max="20" min="1" />
<div>
<input type="checkbox" />
</div>
</div>
<div>
<button onClick={handleMint}>mint</button>
</div>
</div>
);
return <MintBTN />;
}

你可以自己试试。添加数字并点击复选框,然后点击mint。哇,你的输入神奇地消失了。

https://codesandbox.io/s/friendly-buck-6g6oh?file=/src/App.js:0-499

我想我做错了什么,但我还没有意识到。我需要能够在不清除输入的情况下单击按钮或对输入执行onChange事件。出于某种原因,设置状态也让我的页面样式抓狂。不确定发生了什么。我的一些关键依赖关系(如果有帮助的话(。谢谢

"react": "^17.0.2",
"webpack": "^4.19.1"

每次设置状态(setDummy(时,组件都会被重新渲染,并将重置您的输入,因为它们是uncontrolled。您需要通过对这些输入使用状态挂钩来使它们成为controlled

import React, { useState } from "react";
export default function App() {
const [dummy, setDummy] = useState(false);
const [number, setNumber] = useState(0);
const [checked, setChecked] = useState(false);
function handleMint() {
setDummy((dummy) => !dummy);
}
return (
<div>
<div>
<input
className="form-control"
type="number"
max="20"
min="1"
value={number}
onChange={e => setNumber(e.target.value)}
/>
<div>
<input
type="checkbox"
checked={checked}
onChange={e => setChecked(e.target.checked)}
/>
</div>
</div>
<div>
<button onClick={handleMint}>mint</button>
</div>
</div>
);
}

请注意valuechecked属性。它们由每个渲染上的挂钩值设置。现在,请注意onChange属性。每次与输入交互时,它都会更新挂钩值并重新提交组件。通过让React管理valuechecked属性,它将保存每个钩子中输入的值。

看看受控组件和状态挂钩

更新

删除MintBTN功能,因为Nicholas Tower指出

您正在应用程序组件的内部创建MintBTN组件。这不起作用。每次应用程序渲染时,您都会创建一种全新类型的组件。它可能与前一个具有相同的文本,但它是一种新类型,因此react需要卸载旧的文本,然后装载一个新的文本,这将重置存储在任何dom元素中的值,并重置任何react状态。

相反,在应用程序之外创建一次组件。

export default function App() {
const [dummy, setDummy] = useState(false);
function handleMint() {
setDummy((dummy) => !dummy);
}
return <MintBTN onClick={handleMint} />;
}
const MintBTN = ({ onClick }) => {
return (
<div>
<div>
<input className="form-control" type="number" max="20" min="1" />
<div>
<input type="checkbox" />
</div>
</div>
<div>
<button onClick={handleMint}>mint</button>
</div>
</div>
);
};

最新更新