我正在尝试制作一个可以获取其子项在渲染上的位置的函数,以便它可以重新渲染它们而不会重叠(它们是绝对定位的)。const ContentWrapper: React.FC<{article: Article.article.article}> = ({ article }) => { const [footnotePositions, setFootnotePositions] = useState<Number[]>([]); const updatePositions = (footnotePosition) => { setFootnotePositions([...footnotePositions, footnotePosition]); } useEffect(() => { // re position children... idk where to put this haven't gotten this far }, [footnotePositions]) return ( <> {article.map( (x, i) => ( <span key={i}> { x[1]==='' ? <Line>{x[0]}<br/>  </Line> : <> <Line>{x[0]}</Line> <FootnoteRef footnotePosition={updatePositions} /> <Citation footnote={x[1]}/> </> } </span> ))} </> )}我可以调试并看到该updatePositions函数被正确调用,但是它没有正确设置状态(我假设是因为异步性质 setState())。状态仅设置为函数中呈现的最后一个组件的位置map()。如何在不覆盖先前迭代的情况下从回调函数调用 setState?我是否需要绑定回调函数(这在功能组件中是如何工作的)?
1 回答
冉冉说
TA贡献1877条经验 获得超1个赞
状态仅设置为函数中呈现的最后一个组件的位置
map()
。
我认为这表明在循环中对状态更新进行排队并使用基于值的状态更新。IE 每个脚注都已安装并调用footnotePosition
| updatePositions
用他们的位置回调并覆盖先前排队的状态值。
这是您要使用功能状态更新的情况。功能状态更新有点像 reducer 函数,但它只将当前状态作为参数。伪代码看起来像这样
setMyState(state => state + update)
这是我的一个 Demo Codesandbox 来帮助说明两种状态更新之间的区别。
假设您的其余组件逻辑是合理的(我对和数组的相关性有一些不确定性article
footnotePositions
)那么我有以下建议:
更新您的updatePositions
函数以使用功能状态更新。
const updatePositions = (footnotePosition) => { setFootnotePositions(positions => [...positions, footnotePosition]); }
变化不大,但现在您可以对多个状态更新进行排队,并且每个更新都将从先前计算的“下一个状态”值进行更新。
添加回答
举报
0/150
提交
取消