react组件化——context

748 阅读2分钟

什么是context

首先大家要明白一些概念,首先是 react 组件间传递数据是通过 props 向下(也就是想子组件传递),是单向传递的,从父级一层一层地通过 props 地向下传递到子子孙孙,有的时候我们组件一层一层的嵌套多层,这样这种方式一层一层传递麻烦,我们可不可以进行跃层传递,这就会用到 context。

组件化的优点

  1. 增强代码重用性,提高开发效率
  2. 简化操作步骤,提升整个项目的可维护性
  3. 便于协同开发
  4. 注意点:降低耦合性

组件的跨层级通信:context

类似于vue中的provider inject

快速开始

# 生成一个react项目
npx create-react-app context
# 进入并启动项目
cd context
npm start

Context API

1. React.createContext创建context对象

// 新建Context.js
import React from "react";
export const Context=React.createContext();

2. Context.Provider父级创建provider传递参数

  <Context.Provider value={theme}>
       <ContextTypePage/>
   </Context.Provider>

3. 子组件消费(3种途径)

- contextType
//传递一个参数的情况
 import React, { Component } from 'react'
 import {Context} from "../Context"
 export default class ContextTypePage extends Component {
 static contextType=Context;
 render() {
     const {themeColor}=this.context;
     console.log("contextType",this.context)
     return (
         <div className="border">
            <span>我是ContextTypePage页面</span>父级传过来的颜色是——{themeColor}
      	</div>
     )
 }}
 
 //传递两个参数的情况
 import React, { Component } from 'react'
 import {Context,UserContext} from "../Context"
 export default class ContextTypePage extends Component {
 static contextType=Context;
 static contextType=UserContext;
 render() {
     const {themeColor,name}=this.context;//有多个参数后面的会覆盖前面的
     return (
         <div className="border">
            <span>我是ContextTypePage页面</span>
         父级传过来的是——{themeColor}
         <p>传过来的第二个参数:{name}</p>
         </div>
     )
 }}
  注意⚠️:**contextType只可以用在类组件中,多个参数不适合用,后面的会覆盖前面的**
  
  传递一个参数效果如图一:

传递两个参数效果如图二:

- useContext
//传递一个参数情况
 import React from 'react'
 import {Context}from '../Context'
 export default function useContextPage() {
 const theme=React.useContext(Context)
 return (
     <div className="border">
         <span>我是useContextPage页面</span>
         父级传过来的颜色是——{theme.themeColor}
     </div>
 )
 }
 //传递两个参数情况
 import React from 'react'
 import {Context,UserContext}from '../Context'
 export default function useContextPage(props) {
 const theme=React.useContext(Context)
 const user=React.useContext(UserContext)
 return (
     <div className="border">
         <span>我是useContextPage页面</span>
         父级传过来的是——{theme.themeColor}
         <p>传过来的第二个参数:{user.name}</p>
     </div>
 )
 }

注意⚠️:useContext只可以用在函数组件中或者自定义hook,且第二个参数不会覆盖第一个

传递一个参数效果图如下: 传递两个参数效果图如下:

- Consumer
//传递一个参数
	import React, { Component } from 'react'
	import { Context } from '../Context'
	export default class ConsumerPage extends Component {
    	render() {
        	return (
            	<div className="border">
                我是ConsumerPage页面
                <Context.Consumer>
                    {
                        theme=>{
                        return <div>页面父组件传过来的颜色是——{theme.themeColor}
                        </div>
                        }
                    }
                </Context.Consumer>
            </div>
        )
    }
}
//传递两个参数
import React, { Component } from 'react'
import { Context,UserContext } from '../Context'

export default class ConsumerPage extends Component {
    render() {
        return (
            <div className="border">
                我是ConsumerPage页面
                <Context.Consumer>
                    {
                        theme=>{
                        return <div>页面父组件传过来的是——{theme.themeColor}
                          <UserContext.Consumer>
                             {
                                user=><p>我是传过来第二个参数——{user.name}</p>
                             }
                        </UserContext.Consumer>
                        </div>
                        }
                    }
                </Context.Consumer>
               

            </div>
        )
    }
}

注意⚠️:不限制函数组件还是类组件用法比较复杂,也不会存在后者覆盖前者

传递一个参数效果图如下: 传递两个参数效果图如下: