React第十节组件之间传值之context

1、Context 使用creatContext() 和 useContext() Hook 实现多层级传值

概述:

在我们想要每个层级都需要某一属性,或者祖孙之间需要传值时,我们可以使用 props 一层一层的向下传递,或者我们使用更便捷的方案,用 creatContext() 和 useContext() 进行隔代之间传值,这种情况下,我们只需要在使用的组件中书写,而不用每一层级都进行书写

使用中注意事项

a、必须使用 Provider 组件,必须使用 value 接收要传递的 属性:

b、下级会向上找最近 的 Provider 获取其传入的 value

c、传入的 value 可以是任意类型的属性

javascript 复制代码
extport default function MyPar(){
  return(
      <>
          <MyCom.Provider value={属性}>
          </MyCom.Provider>
      </>
  )
}

1.1、基本用法实现上下级数据共享

首先创建通用 ComContext文件

javascript 复制代码
import { createContext } from "react";
// 创建一个 UserInfoContext 组件
export const UserInfoContext = createContext()

其次创建最终使用组件 UserInfo

javascript 复制代码
import {useContext} from 'react'
import { UserInfoContext } from './ComContext'
export default function UseInfo() {
    // 通过 useContext Hook 接收上级 UserInfoContext 传入的内容,总是获取距离最近的 Provider 的 value 值
    const userInfo = useContext(UserInfoContext)
    console.log('==userInfo===', userInfo)
  return (
    <div>
      <h3>用户信息</h3>
      <p>名称:{userInfo.name}</p>
      <p>年龄:{userInfo.age}</p>
    </div>
  )
}

最后在父组件中调用上面两个组件

javascript 复制代码
import { UserInfoContext } from './ComContext'
import UseInfo from './UseInfo'
export default function MyContext2() {

    const userInfo = {
        name: 'Andy',
        age: 18
    }
  return (
    <>
        <h2>第一级:</h2>
        {/* 将普通对象传给下级 */}
        <UserInfoContext.Provider value={userInfo}>
            {/* 这里 不管写多少个 UseInfo 组件,都可以接收到 传入的 userInfo 对象 */}
            <UseInfo></UseInfo>
            <UseInfo></UseInfo>
            <UseInfo></UseInfo>
        </UserInfoContext.Provider>
    </>
  )
}

1.2、Context 与 useState() 使用

通过 useState() 动态修改 userInfo 数据,

javascript 复制代码
import { useState} from 'react'
import { UserInfoContext } from './ComContext'
import UseInfo from './UseInfo'
export default function MyContext2() {
    const [userInfo, setUseInfo] = useState({
        name: 'Andy',
        age: 18
    })
    const hanldeChangeUserInfo = () => {
        setUseInfo({...userInfo, name: `${userInfo.name} + 1`})
    }
  return (
    <>
        <h2>第一级:</h2>
        <button onClick={hanldeChangeUserInfo}>修改name</button>
        <UserInfoContext.Provider value={userInfo}>
            {/* 在下级接收的 userInfo 会实时更新 */}
            <UseInfo></UseInfo>
        </UserInfoContext.Provider>
    </>
  )
}

1.3、Context 树形结构示例

文件目录

声明levelContext文件

import { createContext } from "react";
export const LevelContext = createContext(0)

声明 HeadTitle文件

import  { useContext } from 'react'
import { LevelContext } from "./LevelContext";
export default function HeadTitle({children}) {
	//  使用 LevelContext
    const level = useContext(LevelContext)
    {
        switch(level) {
            case 1:
            return <h1>{`第${level}级`}</h1>
            case 2:
            return <h2>{`第${level}级`}</h2>
            case 3:
            return <h3>{`第${level}级`}</h3>
            case 4:
            return <h4>{`第${level}级`}</h4>
            case 5:
            return <h5>{`第${level}级`}</h5>
        }
    }
}

声明 ContMain 文件

这里使用 nanoid 插件,生成随机id,需要自行安装 yarn add nanoid

import React, { useContext } from 'react'
import HeadTitle from './HeadTitle'
import { LevelContext } from './LevelContext'
import { nanoid } from 'nanoid';
import './index.scss'
export default function ContMain({children}) {
    const level = useContext(LevelContext)
    return (
            <div className="container">
                { 
                    children && children.length && children?.map((item, index) => 
                            <>
                            // 这样 HeadTitle 组件中才能获取到 value 值
                                <LevelContext.Provider key={`${nanoid()}4444`} value={item.level} >
                                    <HeadTitle ></HeadTitle>
                                    <p>姓名:{item.name}</p>
                                    <p>年龄:{item.age}</p>
                                    {
                                        item && item?.children && item?.children.length && (
                                            <div style={{marginLeft: `${item.level * 20}px`}}>
                                            // 自调用当前组件
                                                <ContMain>{[...item.children]}</ContMain>
                                            </div>
                                        ) 
                                    }
                                </LevelContext.Provider>
                            </>
                    )
                }
            </div>
    )
}

声明index 文件

import ContMain from './ContMain'
import { userInfoArr } from './mock.js'
import { LevelContext } from './LevelContext'
export default function MyContext3() {
  return (
    <>
        <h1>父级</h1>
        <LevelContext.Provider value={1}>
            <ContMain >{[...userInfoArr]}</ContMain>
        </LevelContext.Provider>
        
    </>
  )
}

效果如图:

相关推荐
Au_ust14 分钟前
css:项目
前端·css
大浪淘沙102416 分钟前
解决因为数据变化,页面没有变化的情况 , 复习一下使用 vuex 的 modules
前端·javascript·vue.js
秋沐39 分钟前
微前端-MicroApp
前端·react.js·webpack·前端框架·npm
Jiaberrr44 分钟前
打造双层环形图:基础与高级渐变效果的应用
前端·javascript·vue.js·信息可视化·echarts
GISer_Jing1 小时前
React前端面试题详解(一)
前端·react.js·前端框架
呵呵哒( ̄▽ ̄)"1 小时前
React 实战选择互动特效小功能
前端·javascript·react.js
Python私教1 小时前
Docker化部署Django:高效、可扩展的Web应用部署策略
前端·docker·django
YiSLWLL1 小时前
Django+Nginx+uwsgi网站Channels+redis+daphne多人在线聊天实现粘贴上传图片
javascript·python·nginx·django
京东零售技术1 小时前
@技术人,我们京东见!
前端·后端·面试
查拉图斯特拉面条2 小时前
前端页面元素定位与XPath优化
前端·ui·自动化