我想在一个组件中“触发一个事件”,让其他组件“订阅”该事件并在 React 中做一些工作。
例如,这是一个典型的 React 项目。
我有一个模型,从服务器获取数据,并且使用该数据呈现多个组件。
interface Model {
id: number;
value: number;
}
const [data, setData] = useState<Model[]>([]);
useEffect(() => {
fetchDataFromServer().then((resp) => setData(resp.data));
}, []);
<Root>
<TopTab>
<Text>Model with large value count: {data.filter(m => m.value > 5).length}</Text>
</TobTab>
<Content>
<View>
{data.map(itemData: model, index: number) => (
<Item key={itemData.id} itemData={itemData} />
)}
</View>
</Content>
<BottomTab data={data} />
</Root>
在一个子组件中,可以编辑和保存模型。
const [editItem, setEditItem] = useState<Model|null>(null);
<Root>
<TopTab>
<Text>Model with large value count: {data.filter(m => m.value > 5).length}</Text>
</TobTab>
<ListScreen>
{data.map(itemData: model, index: number) => (
<Item
key={itemData.id}
itemData={itemData}
onClick={() => setEditItem(itemData)}
/>
)}
</ListScreen>
{!!editItem && (
<EditScreen itemData={editItem} />
)}
<BottomTab data={data} />
</Root>
让我们假设它是 EditScreen:
const [model, setModel] = useState(props.itemData);
<Input
value={model.value}
onChange={(value) => setModel({...model, Number(value)})}
/>
<Button
onClick={() => {
callSaveApi(model).then((resp) => {
setModel(resp.data);
// let other components know that this model is updated
})
}}
/>
应用程序必须让TopTab
,BottomTab
和ListScreen
组件更新数据
- 无需再次从服务器调用 API(因为 EditScreen.updateData 已经从服务器获取更新的数据)和
- 不将
updateData
函数作为 props传递(因为在大多数实际情况下,组件结构太复杂,无法将所有函数作为 props 传递)
为了有效地解决上述问题,我想用一个参数(更改模型)触发一个事件(例如“模型更新”),并让其他组件订阅该事件并更改它们的数据,例如:
// in EditScreen
updateData().then(resp => {
const newModel = resp.data;
setModel(newModel);
Event.emit("model-updated", newModel);
});
// in any other components
useEffect(() => {
// subscribe model change event
Event.on("model-updated", (newModel) => {
doSomething(newModel);
});
// unsubscribe events on destroy
return () => {
Event.off("model-updated");
}
}, []);
// in another component
useEffect(() => {
// subscribe model change event
Event.on("model-updated", (newModel) => {
doSomethingDifferent(newModel);
});
// unsubscribe events on destroy
return () => {
Event.off("model-updated");
}
}, []);
是否可以使用 React 钩子?
如何在 React 钩子中实现事件驱动的方法?