简体   繁体   English

React 将回调函数传递给多个子组件

[英]React pass callback function to multiple child components

I'm trying to make a function that can get the position of its children on render so that it can re render them without overlap (they are absolutely positioned).我正在尝试制作一个可以在渲染时获取其子项位置的函数,以便它可以重新渲染它们而不会重叠(它们是绝对定位的)。

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/>&emsp;&emsp;</Line>
          :
          <>
            <Line>{x[0]}</Line>
            <FootnoteRef footnotePosition={updatePositions} />
            <Citation footnote={x[1]}/>
          </>
          }
        </span>
      ))}
    </>
  )
}

I can debug and see that the updatePositions function is correctly getting called, however this it doesn't set the state correctly (I assume because of the async nature setState()).我可以调试并看到updatePositions函数被正确调用,但是它没有正确设置状态(我假设是因为 setState() 的异步性质)。 The state is only set with the position of the last component that is rendered in the map() function.状态仅设置为在map()函数中呈现的最后一个组件的位置。

How can I call setState from the callback function without overriding previous iterations?如何在不覆盖先前迭代的情况下从回调函数调用 setState?

Do I need to bind the callback function (how does that work in functional components)?我是否需要绑定回调函数(这在功能组件中是如何工作的)?

The state is only set with the position of the last component that is rendered in the map() function.状态仅设置为在map()函数中呈现的最后一个组件的位置。

I think this is indicative of queueing state updates within a loop and using a value-based state update.我认为这表明在循环中排队状态更新并使用基于值的状态更新。 IE Every foot note is mounted and invokes the footnotePosition | IE 每个脚注都被挂载并调用footnotePosition | updatePositions callback with their position and overwrites the previous enqueued state value. updatePositions回调它们的位置并覆盖之前的入队状态值。

This is the situation you want to use functional state updates.这是您想要使用功能状态更新的情况。 A functional state update is sort of like a reducer function, but it only takes the current state as an argument.功能状态更新有点像减速器函数,但它只将当前状态作为参数。 Pseudo code would look like this伪代码看起来像这样

setMyState(state => state + update)

Here is a Demo Codesandbox of mine to help illustrate the difference between the two types of state update.这是我的一个 Demo Codesandbox 来帮助说明两种状态更新之间的区别。

编辑反应 - 定期和功能状态更新

Assuming the rest of your component logic is sound ( I have some uncertainty about the correlation of the article and footnotePositions arrays ) then I have the following suggestion:假设您的其余组件逻辑是合理的(我对articlefootnotePositions数组的相关性有一些不确定性),那么我有以下建议:

Update your updatePositions function to use functional state updates.更新您的updatePositions函数以使用功能状态更新。

const updatePositions = (footnotePosition) => {
  setFootnotePositions(positions => [...positions, footnotePosition]);
}

Not a big change, but now you can queue up multiple state updates and each update will update from the previously computed "next state" value.变化不大,但现在您可以将多个状态更新排入队列,并且每个更新都将从先前计算的“下一个状态”值进行更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM