反应useState重新渲染太多次

时间:2020-05-01 04:12:35

标签: javascript reactjs react-spring

我正在创建一个带有react的简单轮播,我注意到索引被多次调用,我不明白为什么,这是我的代码段,这里也是完整版本https://codesandbox.io/s/small-bash-4l7ix?file=/src/index.js

...

const pages = [
  React.forwardRef((props, ref) => (
    <animated.div ref={ref} style={{ ...props.style, background: 'lightpink' }}>
      A
    </animated.div>
  )),
  React.forwardRef((props, ref) => (
    <animated.div ref={ref} style={{ ...props.style, background: 'lightblue' }}>
      B
    </animated.div>
  )),
  React.forwardRef((props, ref) => (
    <animated.div ref={ref} style={{ ...props.style, background: 'lightgreen' }}>
      C
    </animated.div>
  )),
]

export default function App() {
  const [index, set] = useState(0)
  const [containerRef, containerSize] = useDimensions()

  const transitions = useTransition(index, p => p, {
    from: { opacity: 0, transform: 'translate3d(100%,0,0)' },
    enter: { opacity: 1, transform: 'translate3d(0%,0,0)' },
    leave: { opacity: 0, transform: 'translate3d(-50%,0,0)' },
  })
  const divStyle = {
    height: `${containerSize.height}px`,
  }

  console.log(index)
  return (
    <>
      <button className={`btn ${index === 0 ? 'btn--active' : ''}`} onClick={() => set(0)}>
        Slide 1
      </button>
      <button className={`btn ${index === 1 ? 'btn--active' : ''}`} onClick={() => set(1)}>
        Slide 2
      </button>
      <button className={`btn ${index === 2 ? 'btn--active' : ''}`} onClick={() => set(2)}>
        Slide 3
      </button>

      <div style={divStyle} className="simple-trans-main">
        {transitions.map(({ item, props, key }) => {
          const Page = pages[item]
          return <Page ref={containerRef} key={key} style={props} />
        })}
      </div>
      <p> Lorem ipusum</p>
    </>
  )
}

...

2 个答案:

答案 0 :(得分:2)

这是因为useTransition

这会创建额外的排序渲染,这就是为什么您看到索引多次打印的原因。

我已经删除了useTransition,您只能在更改index时检查它的打印内容。

在下面检查。

Edit gracious-oskar-h6sci

答案 1 :(得分:2)

为了将组件移入和移出,来自react-spring的useTransition挂钩为您跟踪组件实例。这些额外的渲染是由节点的重叠安装和卸载造成的。

例如:

  1. 从“幻灯片1”开始
  2. 点击“幻灯片2”
  3. 库挂载'Slide 2'//触发重新渲染
  4. 图书馆开始向“幻灯片1”过渡
  5. 库卸载'幻灯片1'//触发重新渲染

每个过渡都被推入数组,并且库按顺序对其进行动画处理。因此,您可以同时触发多个重叠的动画。

在codesandbox中检出React DevTools,您将看到节点正在安装和卸载。

React Devtools in codesandbox