React hooks,每个 child
React hooks, one for each child
我正在使用 useDimensions
挂钩来测量我的 child 组件并因此更新 parent 组件(尽管任何类似的测量挂钩也会发生此问题) .因此,我想 useDimensions
我拥有的每个 child 组件。然而,这是一个通用的 parent 组件,可以接受任意数量的 child 组件,所以我 有 循环 children 并添加一个每个钩子。
目前看起来有点像这样:
import React from "react";
import useDimensions from "react-use-dimensions";
function Parent(props){
const measurements = props.children.map(child => useDimensions());
return props.children.map(
(child, i) => React.cloneElement(child, {ref: measurements[i][0]})
);
}
但是,这会破坏 first rule of hooks:不要在循环、条件或嵌套函数中调用 Hooks。
在不违反 React hooks 规则的情况下,最佳实践方法是什么?
钩子规则的原因在Why Do React Hooks Rely on Call Order中有很好的解释。
如果需要总尺寸,无需单独测量每个 child,这将很容易:
function Parent({children}) {
const [ref] = useDimensions()
return (
<div ref={ref}>
{children}
</div>
)
}
对于更复杂的场景,将 React 代码构造成多个组件是一种有效的方法,"a waste of time" 和 "addition of lots of abstraction" 都不是,例如:
function Parent({children}) {
const measurements = useRef(Array(children.length))
const createSetRef = (i) => (ref) => {
measurements[i] = ref
}
return children.map(
(child, i) => <Child setRef={createSetRef(i)}>{child}</Child>
)
}
function Child({children, setRef}) {
const [ref] = useDimensions()
useEffect(() => setRef(ref), [])
if (React.isValidElement(children)) {
return React.cloneElement(children, {ref})
} else {
console.log("TODO:", children)
return children
}
}
我正在使用 useDimensions
挂钩来测量我的 child 组件并因此更新 parent 组件(尽管任何类似的测量挂钩也会发生此问题) .因此,我想 useDimensions
我拥有的每个 child 组件。然而,这是一个通用的 parent 组件,可以接受任意数量的 child 组件,所以我 有 循环 children 并添加一个每个钩子。
目前看起来有点像这样:
import React from "react";
import useDimensions from "react-use-dimensions";
function Parent(props){
const measurements = props.children.map(child => useDimensions());
return props.children.map(
(child, i) => React.cloneElement(child, {ref: measurements[i][0]})
);
}
但是,这会破坏 first rule of hooks:不要在循环、条件或嵌套函数中调用 Hooks。
在不违反 React hooks 规则的情况下,最佳实践方法是什么?
钩子规则的原因在Why Do React Hooks Rely on Call Order中有很好的解释。
如果需要总尺寸,无需单独测量每个 child,这将很容易:
function Parent({children}) {
const [ref] = useDimensions()
return (
<div ref={ref}>
{children}
</div>
)
}
对于更复杂的场景,将 React 代码构造成多个组件是一种有效的方法,"a waste of time" 和 "addition of lots of abstraction" 都不是,例如:
function Parent({children}) {
const measurements = useRef(Array(children.length))
const createSetRef = (i) => (ref) => {
measurements[i] = ref
}
return children.map(
(child, i) => <Child setRef={createSetRef(i)}>{child}</Child>
)
}
function Child({children, setRef}) {
const [ref] = useDimensions()
useEffect(() => setRef(ref), [])
if (React.isValidElement(children)) {
return React.cloneElement(children, {ref})
} else {
console.log("TODO:", children)
return children
}
}