Store.js:
import {useReducer} from "react";
import {ACTION_TYPES} from "./storeActionTypes";
export const INITIAL_STATE = {
counter: 0,
};
export const storeReducer = (state, action) => {
switch (action.type) {
case ACTION_TYPES.INCREASE_COUNTER_BY_1:
return {
...state,
counter: state.counter + 1,
};
default:
return state;
}
};
const Store = () => {
const [state, dispatch] = useReducer(storeReducer, INITIAL_STATE);
return [state, dispatch];
};
export default Store;
AnyComponent.js
import React from "react";
import Store from "../store/Store";
const AnyComponent = () => {
const [store, dispatch] = Store();
const handleInceaseByOne = (e) => {
e.preventDefault();
dispatch({type: "INCREASE_COUNTER_BY_1"});
};
return (
<div>
<button onClick={(e) => handleInceaseByOne(e)}>Submit</button>
<span>counter from AnyComponent.js:{store.counter}</span>
</div>
);
};
export default AnyComponent;
OtherComponent.js
import React from "react";
import Store from "../store/Store";
const OtherComponent.js = () => {
const [store, dispatch] = Store();
return (
<div>
<span>counter from OtherComponent.js:{store.counter}</span>
</div>
);
};
export default OtherComponent.js;
所以基本上就像Redux一样,创建一个存储所有内容的存储库。在AnyComponent.js中,我们有一个按钮,它将counter加1,这样我们就可以看到AnyComponent.js和OtherComponent.js中store.counter的值。
请任何人告诉我,如果有什么错误的代码?
稍后将尝试将此上传到GitHub。
我在网上找了找,没有找到任何类似的东西,所以请让我知道你的想法。
2条答案
按热度按时间o2gm4chl1#
如果你真的尝试这个,你会发现一个组件的
counter
状态并没有反映在第二个组件上,你并没有创建一个状态,而是创建了两个独立的状态。由于您在每个组件中调用
Store()
,这将导致对useReducer
的新调用,因此您创建了此reducer/state的一个新示例,它是独立的,并且只能从调用它的组件使用(或者如果作为道具向下传递,则是它的子组件)。你在这里所做的就是创建你自己的自定义钩子,这只用于可重用性,而不是共享状态。共享状态可以通过很多其他的选择来实现(比如react context)。
请随时在这个可复制的codesandbox中查看这一点。
ygya80vv2#
从React文档:
“只从React函数组件调用挂钩。不要从常规JavaScript函数调用挂钩。(只有一个其他有效的地方可以调用挂钩--您自己的自定义挂钩。[...]。”(https://reactjs.org/docs/hooks-overview.html)