<select>在React中使用受控的HTML 标签时。
<select>
关于以下代码段:
工作原理:
选项1
function changeSelect(event) { const newValue = event.target.value; setNestedState((prevState) => { return({ ...prevState, propA: newValue }); }); }
这不是吗?(仅在第一次更改时有效)
选项#2
function changeSelect(event) { setNestedState((prevState) => { return({ ...prevState, propA: event.target.value }); }); }
SNIPPET(使用选项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)是一个synthetic event。React重复使用synthetic events,这意味着函数执行完成时,它将使中的event属性无效event pool。
event
synthetic event
React
event pool
由于setState是async和event之后被无效onChange被调用,直接访问事件属性(即event.target.value异步回调中)将无法正常工作。
setState
async
onChange
event.target.value
一种方法是将值从a存储synthetic event到变量中,例如:
function changeSelect(event) { const newValue = event.target.value; // reference setNestedState((prevState) => { return({ ...prevState, propA: newValue // can use event properties }); }); }
使它异步运行的 另一种方法是使用event.persist()。
event.persist()
从文档中,
如果要以异步方式访问事件属性,则应调用event.persist()事件,这将从池中删除综合事件,并允许用户代码保留对该事件的引用。
function changeSelect(event) { event.persist(); //This will persist the event setNestedState((prevState) => { return({ ...prevState, propA: event.target.value }); }); }
演示版