以前可以使用一层一层的往下传递,这种可以解决需求,
1.父组件往孙子组件传值:
App.js
import React, { Component } from 'react'
import Profile from './Profile'
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
nikename:"coderhzc",
level:88
}
}
render() {
const {nikename,level} = this.state
return (
<div>
<Profile nikename={nikename} level={level}/>
</div>
)
}
}
profile.js文件(注意是函数组件)
import React from 'react';
import ProfileHeader from './ProfileHeader';
export default function Profile(props) {
// 从父组件传递过来的
console.log(props,"profile");
return (
<div>
<ProfileHeader nikename={props.nikename} level={props.level}/>
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
)
}
ProfileHeader.js 是profile.js 的子文件 (注意是函数组件)
import React from "react";
export default function ProfileHeader(props) {
console.log(props,"ProfileHeaderProfileHeaderProfileHeader");
return (
<div>
<h2>用户昵称: {props.nikename}</h2>
<h2>用户等級: {props.level}</h2>
</div>
);
}
实际截图
** 以上可以实现但是非父子组件就搞不定了 **
补充以上缺陷使用属性展开 {...props},就可以省略Profile.js中的那段多余的传值
2. 跨组件通讯Context应用场景
Context相关API
(1) React.createContext
--创建一个需要共享的Context对象:
-- 如果一个组件订阅了Context,那么这个组件会从离自身最近的那个匹配的 Provider 中读取到当前的context值;
-- defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值
const myContext = React.create
(2) Context.Provider
-- 每个 Context 对象都会返回一个 Provider React 组件,它允许消费组件订阅 context 的变化:
-- Provider 接收一个 value 属性,传递给消费组件;
-- 一个 Provider 可以和多个消费组件有对应关系;
-- 多个 Provider 也可以嵌套使用,里层的会覆盖外层的数据;
-- 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染;
<MyContext.Provider value={/*某个值*/}>
(3) Class.contextType
-- 挂载在 class 上的 contextType 属性会被重赋值为一个由 React.createContext() 创建的 Context 对象:
-- 这能让你使用 this.context 来消费最近 Context 上的那个值; p 你可以在任何生命周期中访问到它,包括 render 函数中;
MyClass.contextType = MyContext
(4) Context.Consumer
-- 这里,React 组件也可以订阅到 context 变更。这能让你在 函数式组件 中完成订阅 context。
-- 这里需要 函数作为子元素(function as child)这种做法;
-- 这个函数接收当前的 context 值,返回一个 React 节点;
<MyContext.Consumer>
{value => /*基于context值进行渲染*/}
</MyContext.Consumer>
(4.1) Class 类组件的具体使用代码如下:
import React, { Component } from "react";
// 1.创建Context对象
// defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值
// const UserContext = React.createContext(defaultValue)
export const UserContext = React.createContext({
nikename: "aaaaa",
level: -100,
});
// 组件
// 3. 具体的使用方式,记住不能使用函数组件
class ProfileHeader extends Component {
render() {
console.log(this.context);
return (
<div>
<h2>用户昵称: {this.context.nikename}</h2>
<h2>用户等級: {this.context.level}</h2>
</div>
);
}
}
// 4. 把创建的Context对象赋值给ProfileHeader的contextType就可以在孙子组件中拿到从爷爷组件传递的数据了
ProfileHeader.contextType = UserContext;
function Profile(props) {
return (
<div>
<ProfileHeader />
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
)
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
objName: {
nikename: "coderhzc",
level: 88,
},
};
}
render() {
return (
<div>
{/* 2.具体使用 */}
{/*
(1) Provider 接收一个 value 属性,传递给消费组件;
(2) 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染;
*/}
<UserContext.Provider value={this.state.objName}>
<Profile />
</UserContext.Provider>
</div>
);
}
}
实际截图
### (4.2) 函数组件的具体使用代码如下:
import React, { Component } from "react";
// 1.创建Context对象
// defaultValue是组件在顶层查找过程中没有找到对应的Provider,那么就使用默认值
// const UserContext = React.createContext(defaultValue)
const UserContext = React.createContext({
nikename: "aaaaa",
level: -100,
});
// 组件
// 3. 函数组件的具体使用
function ProfileHeader() {
return (
<div>
<UserContext.Consumer>
{
value => {
console.log(value);
return (
<div>
<h2>用户昵称: {value.nikename}</h2>
<h2>用户等級: {value.level}</h2>
</div>
);
}
}
</UserContext.Consumer>
</div>
);
}
function Profile(props) {
return (
<div>
<ProfileHeader />
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
);
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
objName: {
nikename: "coderhzc11",
level: 88,
},
};
}
render() {
return (
<div>
{/* 2.具体使用 */}
{/*
(1) Provider 接收一个 value 属性,传递给消费组件;
(2) 当 Provider 的 value 值发生变化时,它内部的所有消费组件都会重新渲染;
*/}
<UserContext.Provider value={this.state.objName}>
<Profile />
</UserContext.Provider>
</div>
);
}
}
实际截图
5. 多个Context使用代码如下(不推荐做):
import React, { Component } from 'react';
// 创建Context对象
const UserContext = React.createContext({
nickname: "aaaa",
level: -1
})
const ThemeContext = React.createContext({
color: "black"
})
function ProfileHeader() {
// jsx -> 嵌套的方式
return (
<UserContext.Consumer>
{
value => {
return (
<ThemeContext.Consumer>
{
theme => {
return (
<div>
<h2 style={{color: theme.color}}>用户昵称: {value.nickname}</h2>
<h2>用户等级: {value.level}</h2>
<h2>颜色: {theme.color}</h2>
</div>
)
}
}
</ThemeContext.Consumer>
)
}
}
</UserContext.Consumer>
)
}
function Profile(props) {
return (
<div>
<ProfileHeader />
<ul>
<li>设置1</li>
<li>设置2</li>
<li>设置3</li>
<li>设置4</li>
</ul>
</div>
)
}
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
nickname: "kobe",
level: 99
}
}
render() {
return (
<div>
<UserContext.Provider value={this.state}>
<ThemeContext.Provider value={{ color: "red" }}>
<Profile />
</ThemeContext.Provider>
</UserContext.Provider>
</div>
)
}
}