React useState 重新渲染太多次
React useState re rendering too many times
我正在用 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>
</>
)
}
...
这是因为useTransition
.
这会产生额外的渲染效果,这就是为什么您会看到多次打印索引。
我已经删除了 useTransition
,您可以检查它是否仅在 index
更改时打印。
检查下方。
为了转换组件进出 react-spring 的 useTransition 挂钩会为您跟踪组件实例。这些额外的渲染是由节点的重叠安装和卸载引起的。
例如:
- 开始于 'Slide 1'
- 点击'Slide 2'
- 库挂载 'Slide 2' // 触发重新渲染
- 库开始转'Slide 1'出
- 库卸载'Slide 1' // 触发重新渲染
每个转换都被推入数组,库按顺序为它们设置动画。所以你可以同时触发多个重叠的动画。
检查codesandbox中的React DevTools,你会看到节点挂载和卸载。
我正在用 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>
</>
)
}
...
这是因为useTransition
.
这会产生额外的渲染效果,这就是为什么您会看到多次打印索引。
我已经删除了 useTransition
,您可以检查它是否仅在 index
更改时打印。
检查下方。
为了转换组件进出 react-spring 的 useTransition 挂钩会为您跟踪组件实例。这些额外的渲染是由节点的重叠安装和卸载引起的。
例如:
- 开始于 'Slide 1'
- 点击'Slide 2'
- 库挂载 'Slide 2' // 触发重新渲染
- 库开始转'Slide 1'出
- 库卸载'Slide 1' // 触发重新渲染
每个转换都被推入数组,库按顺序为它们设置动画。所以你可以同时触发多个重叠的动画。
检查codesandbox中的React DevTools,你会看到节点挂载和卸载。