React useState数组首次点击赋值不生效,需点击两次才能设置数据是什么原因
问题原因
React的状态更新是异步批量执行的,调用setProjectData之后,当前函数作用域内的projectData不会立刻变更,React会等整个handleSubmit回调执行完毕后,再统一更新状态、触发组件重渲染,重渲染后才会生成新的projectData值。
你在setProjectData之后立刻打印的是当前渲染周期的旧状态值,所以第一次点击打印空数组,第二次点击打印第一次更新后的结果,造成了需要点击两次才生效的错觉,实际上第一次点击后状态已经更新成功,组件重渲染时就能拿到新值。
验证方案
在组件函数顶层加打印,就能看到每次点击后状态的正确变更,也可以直接在页面渲染数组内容直观看到更新结果:
export default function App() { const [title, setTitle] = useState(''); // 建议补初始空字符串,避免undefined问题 const [projectData, setProjectData] = useState([]); // 组件每次重渲染都会执行,输出最新的状态值 console.log('最新projectData:', projectData) const handleSubmit = (e) => { e.preventDefault(); setProjectData([...projectData, { projectTitle: title }]); }; return ( <div className="App"> <input type="text" onChange={(e) => { setTitle(e.target.value); }} /> <button onClick={handleSubmit}>insert</button> {/* 直接渲染数组内容,点击一次就能看到更新结果 */} {projectData.map((item, index) => <p key={index}>{item.projectTitle}</p>)} </div> ); }
需求适配方案
如果你需要在projectData更新完成后执行后续逻辑(比如调用接口、做数据处理),可以用useEffect监听状态变更:
useEffect(() => { // 此处的projectData为更新后的最新值 console.log('状态更新完成,当前值:', projectData) // 在这里写后续要执行的逻辑 }, [projectData])
内容的提问来源于stack exchange,提问作者Bnar Kamal
相关产品推荐
相关产品推荐

