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

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

    开源项目
    • B5LaravelCMF:基于laravel9+bootstrap3实现的快速开发后台
    • B5YiiCMF:基于Yii2+bootstrap3 实现的快速开发后台管理系统
    • B5ThinkCmf:基于ThinkPHP6+bootstrap3 实现的快速开发后台管理系统
    • B5VueCMF_H5:vue3.0 + Webpack/Vite + Vuex + VueRouter + Vant3 搭建快速开发基本Demo
    • See also:gitee.com@b5net
    最新评论
    奥德赛 on Electron+vue搭建项目或将vue项目转为electron :大声道奥术大师大声道
    cmf :我的qq 292864861
    cmf :你好 你的B5ThinkCMF下载后有点问题 能帮忙解决下么?
    laravel新手 :您好,laravel9+bootstrap3实现的快速开发后台,下载部署后,刷新加载,F12我看了下,我部署的是240毫秒左右,您部署的测试版本只有50毫秒左右,能辛苦指导下,如何优化lv吗,谢谢
    瀑布 :你好,yii我下载在本地后台,接口请求非常慢,通过debug我发现session_started执行时间很长,想问下这个是需要哪个地方配置吗?
    瀑布 :你好,今天看到你的开源项目,很喜欢,感谢你的开源
    冰舞 on Laravel定时任务的实现 :测试测试测试测试测试测试 测试测试测试测试测试测试测试测试测试测试
    文章分类