React hooks - useContext

2024-05-29 1059阅读

useContext

        • 用法
        • 使用
          • 以非侵入的方式使用 Context
          • 使用 useContext 重构 useReducer 案例
            用法

            实现多层组件的数据传递

            React hooks - useContext
            (图片来源网络,侵删)
            1. 在全局创建 Context 对象
            2. 在父组件中使用 Context.Provider 提供数据
            3. 在子组件中使用 useContext 使用数据
            import React, { useContext } from 'react'
            // 全局
            const MyContext = React.createContext(初始数据)
            
            // 父组件
            const Father = () => {
              return {name: 'escook', age: 22}}
            }
            
            // 子组件
            const Son = () => {
              const myCtx = useContext(MyContext)
              return 

            姓名:{myCtx.name}

            年龄:{MyCtx.age}

            }
            使用
            // 声明 TS 类型
            type ContextType = { count: number; setCount: React.Dispatch } 
            // 1. 创建 Context 对象
            const AppContext = React.createContext({} as ContextType) 
            
            export const LevelA: React.FC = () => {
              // 定义状态
              const [count, setCount] = useState(0)
              return (
                { padding: 30, backgroundColor: 'lightblue', width: '50vw' }}
                  

            count值是:{count}

            () = setCount((prev) => prev + 1)}>+1 {/* 2. 使用 Context.Provider 向下传递数据 */} { count, setCount }} {/* 使用子组件 */} ) }
            export const LevelB: React.FC = () => {
              return (
                { padding: 30, backgroundColor: 'lightgreen' }}
                  {/* 使用子组件 */}
                  
                
              )
            } 
            
            export const LevelC: React.FC = () => {
              // 3. 使用 useContext 接收数据
              const ctx = useContext(AppContext) 
              return (
                { padding: 30, backgroundColor: 'lightsalmon' }}
                  {/* 4. 使用 ctx 中的数据和方法 */}
                  

            count值是:{ctx.count}

            () = ctx.setCount((prev) => prev + 1)}>+1 () = ctx.setCount(0)}>重置 ) }
            以非侵入的方式使用 Context

            保证父组件中代码的单一性和Provider的通用性,解决父组件中侵入了 的问题,

            Context.Provider 封装到独立的 Wrapper 函数式组件中。

            核心思路:每个 Context 都创建一个对应的 Wrapper 组件,在 Wrapper 组件中使用 Provider 向 children 注入数据。

            // 声明 TS 类型
            type ContextType = { count: number; setCount: React.Dispatch }
            // 创建 Context 对象
            const AppContext = React.createContext({} as ContextType)
            
            // 定义独立的 Wrapper 组件,被 Wrapper 嵌套的子组件会被 Provider 注入数据
            export const AppContextWrapper: React.FC = (props) => {
              // 1. 定义要共享的数据
              const [count, setCount] = useState(0)
              // 2. 使用 AppContext.Provider 向下共享数据
              return { count, setCount }}{props.children}
            } 
            
            import React from 'react'
            import { AppContextWrapper, LevelA } from '@/components/use_context/01.base.tsx'
            const App: React.FC = () => {
              return (
                
                  
                  
                  
                
              )
            }
            export default App 
            

            组件树的嵌套关系为:App => Wrapper => LevelA => LevelB => LevelC。因此在 LevelA、LevelB 和 LevelC 组件中,都可以使用 context 中的数据。

            export const LevelA: React.FC = () => {
              // 使用 useContext 接收数据
              const ctx = useContext(AppContext)
              return (
                { padding: 30, backgroundColor: 'lightblue', width: '50vw' }}
                  {/* 使用 ctx 中的数据和方法 */}
                  

            count值是:{ctx.count}

            () = ctx.setCount((prev) => prev + 1)}>+1 ) }
            export const LevelC: React.FC = () => {
              // 使用 useContext 接收数据
              const ctx = useContext(AppContext)
              return (
                { padding: 30, backgroundColor: 'lightsalmon' }}
                  {/* 使用 ctx 中的数据和方法 */}
                  

            count值是:{ctx.count}

            () = ctx.setCount((prev) => prev + 1)}>+1 () = ctx.setCount(0)}>重置 ) }
            使用 useContext 重构 useReducer 案例
            // 1. 定义 Context 的 TS 类型
            // 在这一步,我们必须先明确要向子组件注入的数据都有哪些
            type UserInfoContextType = { user: UserType; dispatch: React.Dispatch } 
            // 2. 创建 Context 对象
            const UserInfoContext = React.createContext({} as UserInfoContextType) 
            
            // 3. 创建 ContextWrapper 组件
            export const UserInfoContextWrapper: React.FC = ({ children }) => {
              const [state, dispatch] = useImmerReducer(reducer, defaultState, initAction)
              return { user: state, dispatch }}{children}
            } 
            
            import React from 'react'
            import { UserInfoContextWrapper, Father } from '@/components/use_reducer/01.base.tsx'
            const App: React.FC = () => {
              return (
                
                  
                
              )
            }
            export default App 
            
            export const Father: React.FC = () => {
              // 4. 调用 useContext 导入需要的数据
              const { user: state, dispatch } = useContext(UserInfoContext)
              const changeUserName = () => dispatch({ type: 'UPDATE_NAME', payload: '刘龙彬' })
              return (
                
            changeUserName}修改用户名

            {JSON.stringify(state)}

            {/* 5. 这里没有必要再往子组件传递 props 了 */} {/* */}
            ) }
            const Son1: React.FC = () => {
              // 6. 把 props 替换为 useContext() 的调用
              const { dispatch, user } = useContext(UserInfoContext)
              const add = () => dispatch({ type: 'INCREMENT', payload: 1 })
              return (
                

            {JSON.stringify(user)}

            add}年龄+1
            ) }
            const Son2: React.FC = () => {
              // 7. 把 props 替换为 useContext() 的调用
              const { dispatch, user } = useContext(UserInfoContext)
              const sub = () => dispatch({ type: 'DECREMENT', payload: 5 })
              return (
                

            {JSON.stringify(user)}

            sub}年龄-5
            ) }
            const GrandSon: React.FC = () => {
              // 8. 把 props 替换为 useContext() 的调用
              const { dispatch } = useContext(UserInfoContext)
              const reset = () => dispatch({ type: 'RESET' })
              return (
                
                  

            这是 GrandSon 组件

            reset}重置 ) }
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]