使用useSyncExternalStore实现组件通信
在React18的版本中,新添加了一个Hook API:useSyncExternalStore,推荐用于从外部数据源读取和订阅的Hook。
通过使用useSyncExternalStore,也可以用它实现组件间的通信。
import { Fragment, useState, useEffect, useSyncExternalStore, useId } from 'react';
import { createRoot } from 'react-dom/client';
class Store {
valueCache = null;
listeners = [];
subscribe = (listener) => {
this.listeners.push(listener);
return () => {
this.listeners.splice(this.listeners.indexOf(listener), 1);
};
};
getSnapshot = () => {
return this.valueCache;
};
emit() {
this.listeners.forEach((listener) => listener());
}
addValue(value) {
this.valueCache = { value };
this.emit();
}
clearValue() {
this.valueCache = null;
}
}
const store = new Store();
function View(props) {
const valueCache = useSyncExternalStore(store.subscribe, store.getSnapshot);
const [state, setState] = useState([]);
useEffect(function() {
if (valueCache !== null && valueCache.value) {
setState((prevState) => [...prevState, valueCache.value]);
store.clearValue();
}
}, [valueCache]);
return <div>{ state.join(', ') }</div>;
}
function AddValue(props) {
const id = useId();
function handleClick(event) {
const value = document.getElementById(`${ id }-input`).value;
if (value && value !== '') {
store.addValue(value);
}
}
return (
<Fragment>
<input id={ `${ id }-input` } />
<button type="button" onClick={ handleClick }>点击</button>
</Fragment>
);
}
function App(props) {
return (
<div>
<AddValue />
<View />
</div>
);
}
const root = createRoot(document.getElementById('app'));
root.render(<App />);
代码演示
这个例子展示了如何在一个组件内操作,然后将结果传递给另一个组件。
输入文本
展示文字
暂无数据