实现一个React hooks基础状态管理
const createContainer = (initialState) => {
let globalState = initialState
const listeners = Object.fromEntries(Object.keys(initialState).map(key => [key, new Set()]))
const setGlobalState = (key, nextValue) => {
if (typeof nextValue === 'function') {
globalState = { ...globalState, [key]: nextValue(globalState[key]) }
} else {
globalState = { ...globalState, [key]: nextValue }
}
listeners[key].forEach(listener => listener())
}
const useGlobalState = (key) => {
const [state, setState] = useState(globalState[key])
useEffect(() => {
const listener = () => {
setState(globalState[key])
}
listeners[key].add(listener)
listener()
return () => { listeners[key].delete(listener) }
}, [])
return [state, (nextValue) => setGlobalState(key, nextValue)]
}
return {
setGlobalState,
useGlobalState,
}
}
上述的 forceUpdate 为
const useGlobalState = (key) => {
const [state, setState] = useState(globalState[key])
useEffect(() => {
const listener = () => {
setState(globalState[key])
}
listeners[key].add(listener)
listener()
return () => { listeners[key].delete(listener) }
}, [])
return [state, (nextValue) => setGlobalState(key, nextValue)]
}
我们可以利用对象的不想等性质改写forceUpdate 为另外一种形式
const useGlobalState = (key) => {
const [, forceUpdate] = useState({});
useEffect(() => {
const listener = () => {
forceUpdate({});
};
listeners[key].add(listener);
listener();
return () => { listeners[key].delete(listener) };
}, []);
return [globalState[key], (nextValue) => setGlobalState(key, nextValue)];
};
我们可以利用自增数值改写forceUpdate 为另外一种形式
const useGlobalState = (key) => {
const [, forceUpdate] = useState(0);
useEffect(() => {
const listener = () => {
forceUpdate(c => c + 1);
};
listeners[key].add(listener);
listener();
return () => { listeners[key].delete(listener) };
}, []);
return [globalState[key], (nextValue) => setGlobalState(key, nextValue)];
};