B5net

人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

React中使用context,createContext和useContext多级传值,实现任意弹窗登录

Published on:2022-05-12

在React中,数据通过props属性自上而下(由父组件向子组件)传递,当组件层级数量增多时,在每一层传递props则很繁琐。

Context提供了一种新的组件之间共享数据的方式,允许数据隔代传递,而不必显式的通过组件树逐层传递props。


1. 父组件使用Provider生产数据,子组件使用Consumer消费数据
2. 子组件使用useContext接收数据或者Consumer组件渲染
3. 动态和静态Context(父组件更新Context,被Provider包裹的子组件刷新数据,没被Provider包裹的子组件使用Context默认值)
4. 在嵌套组件中更新Context(子组件通过Context传递的函数更新数据)


一、创建context文件login.js


import { createContext } from 'react'
//默认值,可以不设置
const initData = {
    title: '测试数据',
    loginVisible: false,
    setLoginVisible: () => {}
}
const LoginContext = createContext(initData)
export const { Provider, Consumer } = LoginContext
export default LoginContext


二、创建登陆弹窗组件


import React from 'react'
import { Modal, Button } from 'antd'
const LoginModal = ({ loginVisible, setLoginVisible }) => {
    return (
        <Modal centered visible={loginVisible} onCancel={() => setLoginVisible(false)} footer={null}>
            <div>用户名:<input type='text' /></div>
            <div>密码:<input type='text' /></div>
            <div>
                <Button onClick={() => setLoginVisible(false)}>取消</Button>
                <Button type='primary'>登录</Button>
            </div>
        </Modal>
    )
}
export default LoginModal


三、在App.js文件中进行数据传递设置


loginVisible控制登录弹窗的显示隐藏

setLoginVisible 修改loginVisible的方法


import React, { Suspense, useState } from 'react'
import { useRoutes } from 'react-router-dom'
import routes from '@/router'
import PageLoading from '@/components/PageLoading'
import { Provider } from '@/utils/context/login'
import LoginModal from '@/components/LoginModal'

const App = () => {
    const routeList = useRoutes(routes)
    const [loginVisible, setLoginVisible] = useState(false)
    return (
        <>
            {/* 将登录弹窗组件放在顶部,全局都能进行控制 */}
            <LoginModal loginVisible={loginVisible} setLoginVisible={setLoginVisible} />
            <Suspense fallback={<PageLoading />}>
{/* 使用Provider包含路由表组件,这样在所有的页面及组件中都能进行使用 */}
                <Provider value={{ loginVisible, setLoginVisible, title: 'asdasd' }}>{routeList}</Provider>
            </Suspense>
        </>
    )
}

export default App


四、在需要使用的组件中进行操作


import React, { useContext } from 'react'
import LoginContext, { Consumer } from '../utils/context/login'

const Test = () => {
    //使用useContext,参数为创建的context
    //返回的结果就是App.js中的Provider组件的value值
    const { setLoginVisible } = useContext(LoginContext)
    return (
        <div>
            <div>
                {/* 可以在组件中直接使用Consumer组件,里面为一个箭头函数,参数value也是Provider组件的value值 */}
                <Consumer>{(value) => value.title}</Consumer>
                <button onClick={() => setLoginVisible(true)}>点击弹出context的登录框</button>
            </div>
        </div>
    )
}
export default Test




留言列表(0)

    留言

    B5net

    人生是场无尽旅途,欢声笑语,踟蹰彷徨,走过的是岁月,路过的是迷茫。向前,是希望极光;回首,是悠长深巷。

    开源项目
    最新评论
    小白 :大佬您好 请问一下 http://b5laravelcmf.b5net.com/admin这个演示网址的全部代码有吗,gitee上不全呢,还能提供一下吗,感激不尽阿
    tz :大佬 B5YiiCMF 还开放吗
    weifox on GoLang常用的三方库 :还有 https://github.com/golang-module/carbon
    php :关于导出功能:1、B5thinkCMF部署后 参数的导出功能点击后就白屏了,不知道是哪里有问题?2、人员部门的导出功能没看懂怎么配置的? 只是启用exportshow=true吗 方便的话请答复下,谢谢!
    初学者 :您好! 部署了您的B5ThinkCMF,请教下 使用新增功能如何实现二级联动呢 ?谢谢
    11 :22
    pcy :前排围观
    Louis :冰舞的博客使用yii框架做的吧,B5ThinkCMF在本地部署后,登录系统的响应时间要比B5YiiCMF的登录时间长,还有一些Bug待修复
    34 :感谢你的开源项目
    文章分类