问题描述
在 React 中使用受控 HTML 标签时.
When using a controlled HTML <select>
tag in React.
关于下面的片段:
为什么会这样:
选项 #1
function changeSelect(event) {
const newValue = event.target.value;
setNestedState((prevState) => {
return({
...prevState,
propA: newValue
});
});
}
这不是吗?(它仅适用于第一次更改)
And this doesn't? (it works only on the first change)
选项 #2
function changeSelect(event) {
setNestedState((prevState) => {
return({
...prevState,
propA: event.target.value
});
});
}
片段(使用选项 #2)
function App() {
const [nestedState,setNestedState] = React.useState({
propA: 'foo1',
propB: 'bar'
});
function changeSelect(event) {
// const newValue = event.target.value;
setNestedState((prevState) => {
return({
...prevState,
propA: event.target.value // THIS DOES NOT WORK
});
});
}
return(
<React.Fragment>
<div>My nested state:</div>
<div>{JSON.stringify(nestedState)}</div>
<select
value={nestedState.propA}
onChange={changeSelect}
>
<option value='foo1'>foo1</option>
<option value='foo2'>foo2</option>
<option value='foo3'>foo3</option>
</select>
</React.Fragment>
);
}
ReactDOM.render(<App/>, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
推荐答案
这里的event
(onChange) 是一个合成事件
.React
重用了 synthetic event
s,这意味着当函数执行完成时,它会取消 .
Here event
(onChange) is a synthetic event
. React
re-uses synthetic event
s, which means when the function execution completes, it nullifies the event
properties in the event pool
.
由于 setState
是 async
并且 event
在 onChange
被调用后被取消,直接访问事件属性(即event.target.value
) 在异步回调中不起作用.
Since setState
is async
and event
gets nullified after onChange
is invoked, directly accessing event properties (i.e event.target.value
) within the async callback won't work.
一种方法是将来自合成事件
的值存储到一个变量中,例如:
One way is to store the value from a synthetic event
into a variable like:
function changeSelect(event) {
const newValue = event.target.value; // reference
setNestedState((prevState) => {
return({
...prevState,
propA: newValue // can use event properties
});
});
}
另一种使其异步工作的方法是使用event.persist()
.
来自文档,
如果你想以异步方式访问事件属性,你应该在事件上调用event.persist()
,这将从池中删除合成事件并允许引用该事件由用户代码保留.
function changeSelect(event) {
event.persist(); //This will persist the event
setNestedState((prevState) => {
return({
...prevState,
propA: event.target.value
});
});
}
这篇关于反应 HTML 选择元素 onChange 函数,尝试访问“event.target.value"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!