React - useCallback 在 renderProps 函数上抛出错误
React - useCallback throwing error on renderProps function
我在道具中传递 renderProps 函数。我想用 useCallback 包装它,这样优化后的子组件将不会在函数创建时重新渲染。
当用 useCallback 包装函数时我得到这个错误:
Invalid hook call. Hooks can only be called inside of the body of a
function component. This could happen for one of the following
reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
以上none适用于我的情况。
renderCell = React.useCallback((
{
events,
popperPlacement,
popperStyle,
time
}
) => {
const { localeToggle } = this.state;
const { weekStarter, isTimeShown } = this.props;
const eventsListPopperStyle = utils.isWeekFirst(time, weekStarter) ||
utils.isWeekSecond(time, weekStarter) ? { left: '-17% !important' } : { left: '17% !important' };
return (
<MonthlyCell
events={events}
isTimeShown={isTimeShown}
popperPlacement={popperPlacement}
popperStyle={popperStyle}
time={time}
eventsListPopperStyle={eventsListPopperStyle}
/>
)
}, [])
因为挂钩在 class 组件中不起作用,所以引发了错误。
我设法通过为 React.memo 提供第二个参数找到了解决方法。在我提供的函数中,我比较了 prevProps 和 nextProps,当 prop 是一个函数时,我忽略它并且 return 为真。
它可能不适用于每个人,因为有时功能会发生变化,但对于不发生变化的情况,没关系。
const equalizers = {
object: (prevProp, nextProp) => JSON.stringify(prevProp) === JSON.stringify(nextProp),
function: () => true, // disregarding function type props
string: (prevProp, nextProp) => prevProp === nextProp,
boolean: (prevProp, nextProp) => prevProp === nextProp,
number: (prevProp, nextProp) => prevProp === nextProp,
}
export const areEqualProps = (prevProps, nextProps) => {
for (const prop in prevProps) {
const prevValue = prevProps[prop];
const nextValue = nextProps[prop];
if (!equalizers[typeof prevValue](prevValue, nextValue)) { return false; }
}
return true
}
export default React.memo(MyComponent, areEqualProps)
我在道具中传递 renderProps 函数。我想用 useCallback 包装它,这样优化后的子组件将不会在函数创建时重新渲染。
当用 useCallback 包装函数时我得到这个错误:
以上Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
- You might have mismatching versions of React and the renderer (such as React DOM)
- You might be breaking the Rules of Hooks
- You might have more than one copy of React in the same app
none适用于我的情况。
renderCell = React.useCallback((
{
events,
popperPlacement,
popperStyle,
time
}
) => {
const { localeToggle } = this.state;
const { weekStarter, isTimeShown } = this.props;
const eventsListPopperStyle = utils.isWeekFirst(time, weekStarter) ||
utils.isWeekSecond(time, weekStarter) ? { left: '-17% !important' } : { left: '17% !important' };
return (
<MonthlyCell
events={events}
isTimeShown={isTimeShown}
popperPlacement={popperPlacement}
popperStyle={popperStyle}
time={time}
eventsListPopperStyle={eventsListPopperStyle}
/>
)
}, [])
因为挂钩在 class 组件中不起作用,所以引发了错误。 我设法通过为 React.memo 提供第二个参数找到了解决方法。在我提供的函数中,我比较了 prevProps 和 nextProps,当 prop 是一个函数时,我忽略它并且 return 为真。 它可能不适用于每个人,因为有时功能会发生变化,但对于不发生变化的情况,没关系。
const equalizers = {
object: (prevProp, nextProp) => JSON.stringify(prevProp) === JSON.stringify(nextProp),
function: () => true, // disregarding function type props
string: (prevProp, nextProp) => prevProp === nextProp,
boolean: (prevProp, nextProp) => prevProp === nextProp,
number: (prevProp, nextProp) => prevProp === nextProp,
}
export const areEqualProps = (prevProps, nextProps) => {
for (const prop in prevProps) {
const prevValue = prevProps[prop];
const nextValue = nextProps[prop];
if (!equalizers[typeof prevValue](prevValue, nextValue)) { return false; }
}
return true
}
export default React.memo(MyComponent, areEqualProps)