我能够通过以下组件更新上下文:
const LightController: React.FC<LightControllerInterface> = ({ devices }) => {
const { state, dispatch } = useContext(AppContext);
const handleFoo1 = () => {
dispatch({
key: 'foo1',
data: !state.foo1
})
}
const handleFoo2 = () => {
dispatch({
key: 'foo2',
data: !state.foo2
})
}
return (
<div>
<button onClick={handleFoo1}>Foo1</button>
<button onClick={handleFoo2}>Foo2</button>
</div>
);
};
但是,由于handleFoo1
和handleFoo2
函数用于多个组件,因此将其抽象并创建如下所示的共享功能组件将很方便:
//Loader.tsx
export const handleFoo1 = (value) => {
const { state, dispatch } = useContext(AppContext);
dispatch({
key: 'foo1',
data: value
})
}
export const handleFoo2 = (value) => {
const { state, dispatch } = useContext(AppContext);
dispatch({
key: 'foo2',
data: value
})
}
,其用法如下:
import {handleFoo1, handleFoo2} from './loader.tsx'
const LightController: React.FC<LightControllerInterface> = ({ devices }) => {
const { state, dispatch } = useContext(AppContext);
return (
<div>
<button onClick={handleFoo1(!state.foo1)}>Foo1</button>
<button onClick={handleFoo2(!state.foo2)}>Foo2</button>
</div>
);
};
第一个版本可以正常运行,但是使用抽象的功能组件,我会遇到常见错误:
Error: 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:
这里有什么我想念的吗?
谢谢。
答案 0 :(得分:0)
我认为问题出在handleFoo1和handleFoo2函数中,因为它们不返回react元素,而react不将其视为react功能组件
“此函数是有效的React组件,因为它接受带有数据的单个“ props”(代表属性)对象参数,并返回React元素。” https://reactjs.org/docs/components-and-props.html
这就是为什么您会收到这样的错误的原因:“错误:无效的挂接调用。挂钩只能在功能组件的主体内部调用。发生这种情况可能是由于以下原因之一:'
也许最好将调度功能作为第二个参数传递给该功能
export const handleFoo1 = (value, dispatch) => {
dispatch({
key: 'foo1',
data: value
})
}