父->子
父组件将要传递的数据放到子组件的属性上,
// 父组件
class Father extends Component {
render() {
<Son message="msg from father" />
}
}
子组件通过props获取这个值
// 子组件
class Son extends Component {
constructor(props) {
super(props)
}
render() {
<div>
{this.props.message}
</div>
}
}
子->父
子组件向父组件传值使用回调函数,父组件先向子组件传递一个函数,
// 父组件
sonHandler(msg) {
this.setState({
message: msg
})
}
render() {
return <div>
{/*<Redirect />*/}
<h2>{this.state.message}</h2>
<Son click={this.sonHandler.bind(this)} />
</div>
}
然后子组件中触发这个函数,并携带参数,就可以实现将子组件中的数据传递到父组件中
callback = (msg) => {
return () => {
this.props.click(msg)
}
}
render() {
return <div>
<button onClick={this.callback('msg from son')}>click</button>
</div>
}
祖先->后代
祖先到后代之间的传递方式有两种:中间层逐层props和使用context对象。逐层传递在层级较深时会变得很复杂,所以我们只使用context方法。
使用方法:上级组件声明自己支持context,提供一个context对象;子级组获取context
// 为当前的 theme 创建一个 context(“light”为默认值)。
const ThemeContext = React.createContext('light');
// 父组件
class App extends React.Component {
render() {
return (
<ThemeContext.Provider value="dark">
<Toolbar />
</ThemeContext.Provider>
);
}
}
// 子组件
function Toolbar() {
return (
<div>
<ThemedButton />
</div>
);
}
// 孙子组件(类组件)
class ThemedButton extends React.Component {
static contextType = ThemeContext;
render() {
return <Button theme={this.context} />;
}
}
// 孙子组件(函数组件)
export default function ThemedButton() {
return (
<ThemeContext.Consumer>
{theme => (
<Button theme={theme} />
)}
</ThemeContext.Consumer>
)
}
API
React.createContext
创建一个context对象,返回一个Provider,可以设置默认值,当组建没有被Provider包裹时,会使用默认值
Context.Provider
接收一个value属性,传递给消费组件,有多层Provider包裹时,最内层的组件会覆盖其他
Context.Consumer
接收context的值,传递给函数的 value 值等同于往上组件树离这个 context 最近的 Provider 提供的 value 值
Class.contextType
挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象。这能让你使用 this.context 来消费最近 Context 上的那个值。你可以在任何生命周期中访问到它,包括 render 函数中。
class MyClass extends React.Component {
componentDidMount() {
let value = this.context;
/* 在组件挂载完成后,使用 MyContext 组件的值来执行一些有副作用的操作 */
}
componentDidUpdate() {
let value = this.context;
/* ... */
}
componentWillUnmount() {
let value = this.context;
/* ... */
}
render() {
let value = this.context;
/* 基于 MyContext 组件的值进行渲染 */
}
}
MyClass.contextType = MyContext;