组件通信可以分为以下几种:
- 父组件向子组件通信
- 子组件向父组件通信
- 跨级组件的通信及context
- 没有嵌套关系的组件通信
父组件向子组件通信
父组件通过props向子组件传递需要的信息。
子组件向父组件通信
子组件调用porp中传来的父组件的方法达到通信的目的
跨级组件的通信
Context 提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
// Context 可以让我们无须明确地传遍每一个组件,就能将值深入传递进组件树。
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light'); class App extends React.Component {
render() {
// 使用一个 Provider 来将当前的 theme 传递给以下的组件树。
// 无论多深,任何组件都能读取这个值。
// 在这个例子中,我们将 “dark” 作为当前的值传递下去。
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
} // 中间的组件再也不必指明往下传递 theme 了。
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
} class ThemedButton extends React.Component {
// 指定 contextType 读取当前的 theme context。
// React 会往上找到最近的 theme Provider,然后使用它的值。
// 在这个例子中,当前的 theme 值为 “dark”。
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
没有嵌套关系的组件通信
使用events库,收信方在componentDidMount里面注册监听事件,在componentUnMount里销毁该事件。发信方则使用emit方法即可发出通讯消息。(切记,有注册,就得有销毁)
// 使用示例
class List1 extends React.Component{
constructor(props) {
super(props)
this.state = {
text: 'list1'
}
}
render() {
return (
<div>{ this.state.text }</div>
)
}
componentDidMount() {
this.eventEmitter = ee.addListener('changeMessage', (msg) => {
this.setState({
text: msg
})
})
}
componentWillUnmount() {
ee.removeListener(this.eventEmitter)
}
}
class List2 extends React.Component{
handleClick(message) {
ee.emit('changeMessage', message)
}
render() {
return (
<button onClick={ this.handleClick.bind(this, '哈哈')}>点点点</button>
)
}
}