文章目录
context是一种组件通信方式,常用于祖组件与后代组件间通信。
基础样例
新建react项目,主要包含以下文件:
- 模板文件index.html
- 入口文件index.js
- 入口组件App.js
- component/Demo/index.jsx、components/Demo/index.css,即Demo组件
模板文件index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Context</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
入口文件index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
ReactDOM.render(<App/>,document.getElementById("root"));
入口组件App.js
import React, { Component } from 'react'
import Demo from "./components/Demo"
export default class App extends Component {
render() {
return (
<div>
<Demo/>
</div>
)
}
}
Demo组件
Demo/index.css
.a{
width: 500px;
background: orange;
padding: 10px;
}
.b{
background: skyblue;
padding: 10px;
}
.c{
background: lightgray;
padding: 10px;
}
Demo/index.jsx
import React, { Component } from 'react'
import "./index.css";
export default class A extends Component {
state = {
username:"张三"
}
render() {
return (
<div className="a">
<div>我是组件A</div>
<div>我的username是{this.state.username}</div>
<B username={this.state.username}/>
</div>
)
}
}
class B extends Component{
render(){
return (
<div className="b">
<div>我是组件B</div>
<C username={this.props.username}/>
</div>
)
}
}
class C extends Component{
render(){
console.log("this,",this);
return (
<div className="c">
<div>我是组件C</div>
<div>接收到的username是{this.props.username}</div>
</div>
)
}
}
使用context传递数据
- 创建context对象:
const MyContext=React.createContext()
。 - 用context对象的Provider组件包裹祖组件,通过value属性传递数据给后代组件:
<MyContext.Provider value={username}>子组件<MyContext.Provider>
- 后代组件获得数据。有以下两种方式,
第一种,使用context对象的Consumer组件:
<MyContext.Consumer>{ value => {} }</MyContext.Consumer>
。
第二种,仅适用于类组件:
首先,声明本组件接收context对象传递过来的数据:static contextType = MyContext
;
然后,通过this.context
获取从祖组件传递过来的数据。
代码更改仅涉及文件:Demo/index.jsx
后代组件是类组件
第一种写法
import React, { Component,createContext } from 'react'
import "./index.css";
const MyContext = createContext();
const {Provider,Consumer} = MyContext;
export default class A extends Component {
state = {
username:"张三"
}
render() {
const {username} = this.state;
return (
<div className="a">
<div>我是组件A</div>
<div>我的username是{username}</div>
<Provider value={username}>
<B/>
</Provider>
</div>
)
}
}
class B extends Component{
render(){
return (
<div className="b">
<div>我是组件B</div>
<C/>
</div>
)
}
}
class C extends Component{
render(){
return (
<div className="c">
<div>我是组件C</div>
<Consumer>
{
value => <div>接收到的username是{value}</div>
}
</Consumer>
</div>
)
}
}
第二种写法
import React, { Component,createContext } from 'react'
import "./index.css";
const MyContext = createContext();
const {Provider} = MyContext;
export default class A extends Component {
state = {
username:"张三"
}
render() {
const {username} = this.state;
return (
<div className="a">
<div>我是组件A</div>
<div>我的username是{username}</div>
<Provider value={username}>
<B/>
</Provider>
</div>
)
}
}
class B extends Component{
render(){
return (
<div className="b">
<div>我是组件B</div>
<C/>
</div>
)
}
}
class C extends Component{
static contextType = MyContext;
render(){
return (
<div className="c">
<div>我是组件C</div>
<div>接收到的username是{this.context}</div>
</div>
)
}
}
后代组件是函数组件
import React, { Component,createContext } from 'react'
import "./index.css";
const MyContext = createContext();
const {Provider,Consumer} = MyContext;
export default class A extends Component {
state = {
username:"张三"
}
render() {
const {username} = this.state;
return (
<div className="a">
<div>我是组件A</div>
<div>我的username是{username}</div>
<Provider value={username}>
<B/>
</Provider>
</div>
)
}
}
class B extends Component{
render(){
return (
<div className="b">
<div>我是组件B</div>
<C/>
</div>
)
}
}
function C(){
return (
<div className="c">
<div>我是组件C</div>
<Consumer>
{
value => <div>接收到的username是{value}</div>
}
</Consumer>
</div>
)
}