返回
React 组件通讯的那些“事儿”
前端
2024-02-15 23:19:24
React 组件之间的通讯方式有很多种,每种方式都有其自身的优缺点。在实际开发中,我们需要根据具体情况选择最合适的方式。
父子组件之间的通讯
父子组件之间的通讯是最简单的一种通讯方式。父组件可以通过 props 向子组件传递数据,子组件可以通过 state 向父组件传递数据。
父组件向子组件传递数据
父组件可以通过 props 向子组件传递数据。props 是一个只读的对象,子组件可以通过 props 来访问父组件传递的数据。
// 父组件
class ParentComponent extends React.Component {
render() {
return (
<div>
<ChildComponent name="John" />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
</div>
);
}
}
子组件向父组件传递数据
子组件可以通过 state 向父组件传递数据。state 是一个可变的对象,子组件可以通过 setState() 方法来修改 state。父组件可以通过子组件的 props 来访问子组件的 state。
// 子组件
class ChildComponent extends React.Component {
state = {
count: 0
};
incrementCount = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<h1>Count: {this.state.count}</h1>
<button onClick={this.incrementCount}>Increment</button>
</div>
);
}
}
// 父组件
class ParentComponent extends React.Component {
render() {
return (
<div>
<ChildComponent />
</div>
);
}
}
兄弟组件之间的通讯
兄弟组件之间的通讯可以分为两种情况:
- 同级兄弟组件之间的通讯 :同级兄弟组件可以通过 props 来传递数据。
- 非同级兄弟组件之间的通讯 :非同级兄弟组件之间的通讯可以使用 context、refs、render props 或高阶组件来实现。
同级兄弟组件之间的通讯
同级兄弟组件之间的通讯可以通过 props 来传递数据。
// 组件 A
class ComponentA extends React.Component {
render() {
return (
<div>
<ComponentB name="John" />
</div>
);
}
}
// 组件 B
class ComponentB extends React.Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
</div>
);
}
}
非同级兄弟组件之间的通讯
非同级兄弟组件之间的通讯可以使用 context、refs、render props 或高阶组件来实现。
context
context 是一个共享的数据对象,可以被所有子组件访问。
// 父组件
class ParentComponent extends React.Component {
state = {
count: 0
};
render() {
return (
<div>
<ChildComponentA />
<ChildComponentB />
</div>
);
}
}
// 子组件 A
class ChildComponentA extends React.Component {
static contextType = MyContext;
render() {
return (
<div>
<h1>Count: {this.context.count}</h1>
</div>
);
}
}
// 子组件 B
class ChildComponentB extends React.Component {
static contextType = MyContext;
render() {
return (
<div>
<h1>Count: {this.context.count}</h1>
</div>
);
}
}
// 创建 context 对象
const MyContext = React.createContext({
count: 0
});
refs
refs 可以用来访问子组件的实例。
// 父组件
class ParentComponent extends React.Component {
childRef = React.createRef();
render() {
return (
<div>
<ChildComponent ref={this.childRef} />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
render() {
return (
<div>
<h1>Hello, {this.props.name}!</h1>
</div>
);
}
}
render props
render props 是一个函数,可以被子组件调用。子组件可以通过 render props 来访问父组件的数据和方法。
// 父组件
class ParentComponent extends React.Component {
state = {
count: 0
};
render() {
return (
<div>
<ChildComponent render={(count) => <h1>Count: {count}</h1>} />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
render() {
return this.props.render(this.props.count);
}
}
高阶组件
高阶组件是一个函数,可以用来包装其他组件。高阶组件可以通过 props 来向被包装的组件传递数据和方法。
// 高阶组件
const withCount = (WrappedComponent) => {
return class extends React.Component {
state = {
count: 0
};
render() {
return <WrappedComponent count={this.state.count} />;
}
};
};
// 被包装的组件
const ChildComponent = (props) => {
return (
<div>
<h1>Count: {props.count}</h1>
</div>
);
};
// 使用高阶组件
const CountComponent = withCount(ChildComponent);
跨级组件之间的通讯
跨级组件之间的通讯可以使用 context、refs、render props 或高阶组件来实现。
// 父组件
class ParentComponent extends React.Component {
state = {
count: 0
};
render() {
return (
<div>
<GrandchildComponent count={this.state.count} />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
render() {
return (
<div>
<GrandchildComponent count={this.props.count} />
</div>
);
}
}
// 孙组件
class GrandchildComponent extends React.Component {
render() {
return (
<div>
<h1>Count: {this.props.count}</h1>
</div>
);
}
}
非嵌套组件之间的通讯
非嵌套组件之间的通讯可以使用 Redux、消息总线或自定义事件来实现。
Redux
Redux 是一个状态管理库,可以用来在组件之间共享数据。
// 创建 Redux store
const store = createStore(reducer);
// 父组件
class ParentComponent extends React.Component {
componentDidMount() {
store.subscribe(() => this.forceUpdate());
}
render() {
return (
<div>
<ChildComponent />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
componentDidMount() {
store.subscribe(() => this.forceUpdate());
}
render() {
return (
<div>
<h1>Count: {store.getState().count}</h1>
</div>
);
}
}
消息总线
消息总线是一个组件,可以用来在组件之间发送和接收消息。
// 创建消息总线
const bus = new EventEmitter();
// 父组件
class ParentComponent extends React.Component {
componentDidMount() {
bus.on('count-updated', () => this.forceUpdate());
}
render() {
return (
<div>
<ChildComponent />
</div>
);
}
}
// 子组件
class ChildComponent extends React.Component {
componentDidMount() {
bus.on('count-updated', () => this.forceUpdate());
}
incrementCount = () => {
bus.emit