【发布时间】:2020-02-06 23:26:20
【问题描述】:
基于状态数组创建组件并为每个组件赋予数组的 setState 属性会导致奇怪的行为。也许是由于并行状态变化?试试下面的 sn-p。单击一个正方形应将其删除。相反,总是会删除最后创建的方格。
问题似乎在于Square 组件中的useEffect()。虽然在 sn-p 中它真的没用,但我使用类似的东西来使元素可拖动。有人可以解释这种行为并提出解决方案吗?我觉得我在这里错过了一些关于 React 的重要内容。
function Square(props){
const [pos, setPos] = React.useState([props.top, props.left])
React.useEffect(() => {
props.setSquares(prevState => prevState.map((square, index) => index === props.index ? {...square, top: pos + 20} : square
))
}, [pos])
function deleteMe(){
props.setSquares(prevState => prevState.filter((square, index) => index !== props.index))
}
return <div onClick={deleteMe}
style={{top: pos[0]+'px', left: pos[1]+'px'}}
className='square'>
</div>
}
function App(){
const [squares, setSquares] = React.useState([
{top: 20, left: 0},{top: 20, left: 100},
{top: 20, left: 200},{top: 20, left: 300}])
React.useEffect(() => console.log('rerender', ...squares.map(s => s.left)))
return <div>{squares.map((square, index) => <Square
setSquares={setSquares} index={index}
top={square.top} left={square.left}/>)}</div>
}
ReactDOM.render(<App/>, document.getElementById('root'))
.square{
position: absolute;
width: 80px;
height: 80px;
background: orange;
}
<div id='root'></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.6/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.6/umd/react-dom.production.min.js"></script>
编辑:正如尼克在 cmets 中建议的那样,我将 setSquare 方法更改为使用 prevState.map 和 filter,以免不自觉地更改以前的状态。
问题仍然存在……屏幕上的最后一个方块总是消失。对每次重新渲染使用效果表明状态得到正确更新。我在这里错过了什么?
【问题讨论】:
标签: javascript reactjs react-state-management react-state