Next.js/React中数组状态变更未触发组件重新渲染问题咨询
问题根因
这不是正常行为,核心问题出在你更新selectedPlaces状态的方式不符合React的状态不可变原则:
你直接在传入setSelectedPlaces的回调函数里对原数组执行push操作,之后直接返回了原数组。React对状态更新执行的是浅比较逻辑,如果新状态和旧状态的引用完全一致,React会判定状态没有发生变化,因此不会触发组件重渲染。你在控制台能看到状态值更新,是因为数组本身的内容确实被你修改了,但React没有感知到这个变更,所以不会主动刷新页面。
修复方案
修改状态时不要修改原数组,始终返回新的数组引用即可:
模拟逻辑修复版
setSelectedPlaces(selected => { // 用扩展运算符创建新数组,添加元素后返回 return [...selected, "dummy data to simplify"] })
实际业务逻辑版本(实现ID的添加/移除切换)
setSelectedPlaces(selected => { // 如果当前ID已存在就过滤掉,不存在就添加 return selected.includes(id) ? selected.filter(item => item !== id) : [...selected, id] })
额外注意事项
你的JSX代码里的三元表达式外层缺少{}包裹,在JSX中嵌入JS表达式需要用大括号包裹,否则会被当成普通文本渲染,完整的可运行参考代码如下:
return ( <div> <div> You have selected {selectedPlaces.length} total places </div> {/* 用{}包裹JS表达式 */} {places === false ? <div>Loading...</div> : places.map(place => { const {name, id} = place // 循环渲染元素需要加唯一key属性,避免React渲染异常 return <div key={id} onClick={() => { setSelectedPlaces(selected => { return selected.includes(id) ? selected.filter(item => item !== id) : [...selected, id] }) }} >{name}</div> }) } </div> )
内容的提问来源于stack exchange,提问作者Jack Hales
相关产品推荐
相关产品推荐

