useSyncExternalStore 介绍
useSyncExternalStore是React 18中新引入的一个Hook,主要用于将组件状态与外部的状态进行同步。主要使用场景如下:
- 外部状态的变化需要影响到组件状态时,可以使用useSyncExternalStore将外部状态与组件状态进行同步,当外部状态发生变化时,组件状态也会同步更新。
- 组件状态的变化需要影响到外部状态时,可以使用useSyncExternalStore将组件状态与外部状态进行同步,当组件状态发生变化时,外部状态也会同步更新。
- 多个组件需要共享同一个状态时,可以使用useSyncExternalStore将多个组件的状态与同一个外部状态进行同步,从而实现状态共享。
如何使用 useSyncExternalStore
使用useSyncExternalStore的示例代码如下:
import { useSyncExternalStore } from 'react18';
function MyComponent() {
const [externalState, setExternalState] = useState({ value: 0 });
const [internalState, setInternalState] = useState(0);
useSyncExternalStore(externalState, setExternalState);
const handleInternalStateChange = (newValue) => {
setInternalState(newValue);
};
return (
<>
<div>External state: {externalState.value}</div>
<div>Internal state: {internalState}</div>
<button onClick={() => handleInternalStateChange(internalState + 1)}>Increment internal state</button>
</>
);
}
在上述示例中,我们通过useSyncExternalStore将组件内部的internalState和外部的externalState进行同步。当我们在组件中使用setInternalState来更新组件状态时,useSyncExternalStore会自动将更新后的状态同步到外部的externalState中,从而实现状态同步功能。
基于useSyncExternalStore进行状态管理
我们可以通过这个api自行设计一个redux + react-redux的数据方案:
设计store
首先我们要设计一个store,它必须有如下属性:
- currentState:当前状态
- subscribe:提供状态发生变化时的订阅能力
- getSnapshot: 获取当前状态 以及改变state的方法,这里参考redux,设计了dispatch、reducer
const store = {
currentState:{data:0},
listeners:[],
reducer(action){
switch(action.type) {
case 'ADD':
return {data:store.currentState.data+1}
default:
return store.state
}
},
subscribe(l){
store.listeners.push(l)
},
getSnapshot() {
return store.currentState
},
dispatch(action) {
store.currentState = store.reducer(action)
store.listeners.forEach(l=>l())
return action;
}
}
使用useSyncExternalStore创建state
import {useSyncExternalStore} from 'react';
function Demo() {
const state = useSyncExternalStore(store.subscribe, ()=>store.getSnapshot().data);
return <div className='p-100'>
<div>count:{state}</div>
<div>
<button onClick={()=>store.dispatch({type:'ADD'})}>add+</button>
</div>
</div>
}
export default Demo;
useSyncExternalStore会执行store.subscribe,并传入一个函数,当store中状态发生变更时,执行这个函数,便可以触发组件的更新。