组件间通讯
组件间的通讯有很多种,常见的主要是父子组件之间、同级组件之间和任意组件之间。
父子组件通讯
父子组件通讯主要依靠props
。父组件可以通过props
将信息传递给子组件,子组件还可以通过props
中父组件指定的回调函数来将信息传递回父组件。具体实现可参考以下示例。
// 父组件
function ParentElement() {
const [info, setInfo] = useState(0);
const handleChange = (e) => {
setInfo(e);
};
return <ChildElement value={info} onValueChange={handleChange} />;
}
// 子组件
function ChildElement(props) {
const handleChange = (e) => {
props.onValueChange(e.target.value);
};
return <input value={props.value} onChange={handleChange} />;
}
同级组件通讯
同级组件之间的通讯无论使用哪种方案解决,都还是需要其共同的父级组件来介导一下的。除了可以使用上面提到的父子组件通讯方法,还可以使用 Context 来形成一个 API 来传递通讯。
const SharedStateContext = createContext();
const ParentComponent = () => {
const [sharedState, setSharedState] = useState("");
return (
<SharedStateContext.Provider value={{ sharedState, setSharedState }}>
<ChildComponentA />
<ChildComponentB />
</SharedStateContext.Provider>
);
};
const ChildComponentA = () => {
const { sharedState, setSharedState } = useContext(SharedStateContext);
return (
<div>
<input
type="text"
value={sharedState}
onChange={(e) => setSharedState(e.target.value)}
placeholder="Type in A"
/>
</div>
);
};
const ChildComponentB = () => {
const { sharedState } = useContext(SharedStateContext);
return (
<div>
<p>Shared state in B: {sharedState}</p>
</div>
);
};
任意组件间通讯
任意组件之间的通讯就要复杂一些了,首先的困难就是无法确定组件之间的共同祖先,其次如果将大量的 Context API 放置在应用的根节点上,可能会给应用带来不必要的开销。所以在这种情况下,可以利用现有的事件系统来实现,或者字型构建一个事件系统。这里借用events
库来完成任意组件之间的通讯。
import EventEmitter from "events";
import { useEffect, useState } from "react";
const eventEmitter = new EventEmitter();
const ChildComponentA = () => {
const [value, setValue] = useState("");
const handleChange = (e) => {
setValue(e.target.value);
eventEmitter.emit("update", e.target.value);
};
return (
<div>
<input
type="text"
value={value}
onChange={handleChange}
placeholder="Type in A"
/>
</div>
);
};
const ChildComponentB = () => {
const [sharedState, setSharedState] = useState("");
useEffect(() => {
eventEmitter.on("update", setSharedState);
return () => {
eventEmitter.off("update", setSharedState);
};
}, []);
return (
<div>
<p>Shared state in B: {sharedState}</p>
</div>
);
};
const ParentComponent = () => (
<div>
<ChildComponentA />
<ChildComponentB />
</div>
);