React.createContext 的 多种使用方法 详细实现方案代码

React.createContext 是 React 的上下文 API 的核心方法之一,提供了一种无需通过组件树逐层传递 props 的方式来共享数据。它特别适合于全局状态的管理,比如用户信息、主题设置等。下面我将详细介绍 React.createContext 的多种使用方法,并提供相应的代码示例。

1. 基础使用

  • 目的:在父组件中定义一个 Context,子组件可以直接通过 useContext 来获取上下文中的数据。

示例

import React, { createContext, useContext } from 'react';

// 创建一个 Context
const MyContext = createContext();

const GrandChild = () => {
    const value = useContext(MyContext); // 使用 useContext 获取数据
    return <div>{value}</div>;
};

const Child = () => <GrandChild />;

const Parent = () => {
    const contextValue = "Hello from Context";
    return (
        <MyContext.Provider value={contextValue}>
            <Child />
        </MyContext.Provider>

    );
};

export default Parent;

2. 使用 Context 传递对象

  • 目的:在 Context 中传递一个复杂的数据结构,比如对象或数组。

示例

import React, { createContext, useContext } from 'react';

// 创建一个 Context
const UserContext = createContext();

const UserProfile = () => {
    const user = useContext(UserContext); // 使用 useContext 获取对象
    return (
        <div>
            <p>Name: {user.name}</p>

            <p>Age: {user.age}</p>

        </div>

    );
};

const Parent = () => {
    const user = { name: "John Doe", age: 30 };
    return (
        <UserContext.Provider value={user}>
            <UserProfile />
        </UserContext.Provider>

    );
};

export default Parent;

3. 使用 Context 与 useState 配合

  • 目的:在 Context 中传递动态状态,可以在组件中修改 Context 中的数据。

示例

import React, { createContext, useContext, useState } from 'react';

// 创建一个 Context
const CounterContext = createContext();

const CounterDisplay = () => {
    const [count] = useContext(CounterContext); // 通过 useContext 获取 count
    return <div>Count: {count}</div>;
};

const CounterControls = () => {
    const [, setCount] = useContext(CounterContext); // 通过 useContext 获取 setCount
    return (
        <button onClick={() => setCount(prev => prev + 1)}>
            Increment
        </button>

    );
};

const Parent = () => {
    const counterState = useState(0); // 使用 useState 创建计数器状态
    return (
        <CounterContext.Provider value={counterState}>
            <CounterDisplay />
            <CounterControls />
        </CounterContext.Provider>

    );
};

export default Parent;

4. 多 Context 配合使用

  • 目的:在一个组件中使用多个 Context,分别传递不同的状态或数据。

示例

import React, { createContext, useContext } from 'react';

// 创建两个 Context
const ThemeContext = createContext();
const UserContext = createContext();

const Dashboard = () => {
    const theme = useContext(ThemeContext);
    const user = useContext(UserContext);
    return (
        <div style={{ background: theme.background, color: theme.color }}>
            <p>Welcome, {user.name}</p>

        </div>

    );
};

const Parent = () => {
    const theme = { background: "black", color: "white" };
    const user = { name: "Jane Doe" };
    return (
        <ThemeContext.Provider value={theme}>
            <UserContext.Provider value={user}>
                <Dashboard />
            </UserContext.Provider>

        </ThemeContext.Provider>

    );
};

export default Parent;

5. Context API 与 useReducer 结合

  • 目的:在复杂状态管理中,通过 useReducer 管理状态,并将其与 Context 结合使用。

示例

import React, { createContext, useContext, useReducer } from 'react';

// 创建一个 Context
const CounterContext = createContext();

// 定义 reducer 函数
const counterReducer = (state, action) => {
    switch (action.type) {
        case 'increment':
            return { count: state.count + 1 };
        case 'decrement':
            return { count: state.count - 1 };
        default:
            return state;
    }
};

const CounterDisplay = () => {
    const { state } = useContext(CounterContext); // 获取 state
    return <div>Count: {state.count}</div>;
};

const CounterControls = () => {
    const { dispatch } = useContext(CounterContext); // 获取 dispatch
    return (
        <>
            <button onClick={() => dispatch({ type: 'increment' })}>
                Increment
            </button>

            <button onClick={() => dispatch({ type: 'decrement' })}>
                Decrement
            </button>

        </>
    );
};

const Parent = () => {
    const [state, dispatch] = useReducer(counterReducer, { count: 0 }); // 使用 useReducer
    return (
        <CounterContext.Provider value={{ state, dispatch }}>
            <CounterDisplay />
            <CounterControls />
        </CounterContext.Provider>

    );
};

export default Parent;

6. 全局 Context

  • 目的:创建一个全局的 Context,通常用于应用级别的状态管理,比如用户认证信息。

示例

import React, { createContext, useContext, useState } from 'react';

// 创建全局 Context
const AuthContext = createContext();

export const useAuth = () => {
    return useContext(AuthContext); // 自定义 Hook 方便使用
};

const AuthProvider = ({ children }) => {
    const [isAuthenticated, setAuthenticated] = useState(false);

    const login = () => setAuthenticated(true);
    const logout = () => setAuthenticated(false);

    return (
        <AuthContext.Provider value={{ isAuthenticated, login, logout }}>
            {children}
        </AuthContext.Provider>

    );
};

const Dashboard = () => {
    const { isAuthenticated, logout } = useAuth();
    return (
        <div>
            {isAuthenticated ? (
                <>
                    <p>Welcome, User!</p>

                    <button onClick={logout}>Logout</button>

                </>
            ) : (
                <p>Please log in.</p>

            )}
        </div>

    );
};

const App = () => {
    return (
        <AuthProvider>
            <Dashboard />
        </AuthProvider>

    );
};

export default App;

这些例子展示了 React.createContext 的多种使用方法,从简单的数据共享到复杂的状态管理,希望能帮助你更好地理解和应用 Context API

7.例子:

案例 1: createContext封装 A组件 ,在A组件里 请求接口结果 赋值 useState 的变量 value。 然后在B组件 使用 A组件 包裹 C组件 在 C组件 获取使用 A组件里的 变量value 的值

你可以通过封装 Context 来实现这个功能。在 A 组件中,我们会使用 useContextuseState 来管理状态,并通过调用接口将结果赋值给 useState 的变量 value。然后在 B 组件中,将 C 组件包裹在 A 组件内,使得 C 组件能够通过 useContext 获取 value 的值。

以下是详细的实现步骤和代码示例:

1. 创建 A 组件并封装 Context

首先,在 A 组件中,我们会创建一个 Context,然后使用 useState 来管理状态,并在 useEffect 中调用接口获取数据,将结果存储在 value 中。最后,我们通过 Context.Providervalue 传递给子组件。

import React, { createContext, useState, useEffect, useContext } from 'react';

// 创建 Context
const MyContext = createContext();

// 封装 A 组件
export const A = ({ children }) => {
    const [value, setValue] = useState(null);

    useEffect(() => {
        // 模拟请求接口,获取数据
        const fetchData = async () => {
            const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
            const data = await response.json();
            setValue(data);
        };

        fetchData();
    }, []);

    return (
        <MyContext.Provider value={value}>
            {children}
        </MyContext.Provider>

    );
};

// 创建自定义 Hook 方便获取 Context 值
export const useMyContext = () => {
    return useContext(MyContext);
};
2. 在 B 组件中使用 A 组件包裹 C 组件

B 组件中,我们将 C 组件包裹在 A 组件内,使 C 组件能够访问 A 组件中的 value 值。

import React from 'react';
import { A } from './A';  // 引入 A 组件
import C from './C';      // 引入 C 组件

const B = () => {
    return (
        <A>
            <C />
        </A>

    );
};

export default B;
3. 在 C 组件中获取 value 的值

C 组件中,我们通过 useMyContext 自定义 Hook 获取 A 组件中的 value 值,并将其展示在界面上。

import React from 'react';
import { useMyContext } from './A';  // 使用自定义 Hook 获取 Context 值

const C = () => {
    const value = useMyContext();

    return (
        <div>
            {value ? (
                <div>
                    <h1>{value.title}</h1>

                    <p>{value.body}</p>

                </div>

            ) : (
                <p>Loading...</p>

            )}
        </div>

    );
};

export default C;
4. 最终的结构

最终的组件层级结构是:

  • B 组件使用 A 组件包裹 C 组件。
  • A 组件负责请求数据并通过 Context 传递数据。
  • C 组件通过 useMyContext 获取 A 组件中的 value 值并展示。
5. 运行效果

当你运行这个示例时,C 组件会首先显示 Loading...,在 A 组件成功请求接口并赋值 value 后,C 组件会显示接口返回的 titlebody 信息。

这个实现方案清晰地展示了如何在 React 中使用 createContext 封装组件,并在子组件中获取并使用封装组件中的状态数据。

案例 2: createContext封装 A组件 ,在A组件里 请求接口结果 赋值 useState 的变量 value。 然后在B组件 获取使用 A组件里的 变量value 的值

要在 React 中实现 createContext 封装的 A 组件,并在 B 组件中获取并使用 A 组件中的 value 值,你可以按照以下步骤进行。

1. 创建 A 组件并封装 Context

首先,创建 A 组件,并在其中使用 useContextuseState 来管理状态。通过 useEffect 调用接口,将返回的数据存储在 value 中。然后通过 Context.Providervalue 传递给 B 组件。

import React, { createContext, useState, useEffect } from 'react';

// 创建 Context
const MyContext = createContext();

// 封装 A 组件
export const A = ({ children }) => {
    const [value, setValue] = useState(null);

    useEffect(() => {
        // 模拟请求接口,获取数据
        const fetchData = async () => {
            const response = await fetch('https://jsonplaceholder.typicode.com/posts/1');
            const data = await response.json();
            setValue(data);
        };

        fetchData();
    }, []);

    return (
        <MyContext.Provider value={value}>
            {children}
        </MyContext.Provider>

    );
};

// 创建自定义 Hook 方便获取 Context 值
export const useMyContext = () => {
    return React.useContext(MyContext);
};
2. 在 B 组件中获取 value 的值

B 组件中,使用 A 组件包裹内容,并通过 useMyContext 自定义 Hook 获取 value 的值。

import React from 'react';
import { A, useMyContext } from './A';  // 引入 A 组件和自定义 Hook

const B = () => {
    const value = useMyContext();  // 获取 A 组件中的 value

    return (
        <A>
            <div>
                {value ? (
                    <div>
                        <h1>{value.title}</h1>

                        <p>{value.body}</p>

                    </div>

                ) : (
                    <p>Loading...</p>

                )}
            </div>

        </A>

    );
};

export default B;
3. 代码解释
  • A 组件:通过 createContext 创建了一个上下文 MyContext。在 A 组件内部,使用 useState 来定义 value,通过 useEffect 调用接口将数据保存到 value 中。最后,通过 MyContext.Providervalue 传递给子组件。
  • useMyContext 自定义 Hook:这是一个简单的 Hook,方便在 B 组件中直接获取 MyContext 的值。
  • B 组件:在 B 组件中,通过 useMyContext 获取 A 组件中的 value 值,然后展示出来。如果 value 为空,则显示 Loading...
4. 运行效果

当你运行这个示例时,B 组件会首先显示 Loading...。一旦 A 组件完成数据请求并赋值 value 后,B 组件会显示接口返回的 titlebody 信息。

这种方法通过 createContext 以及 Context.Provider 实现了在不同组件间的状态共享,并避免了繁琐的 props 传递,代码结构更加清晰且易于维护。

  • 10
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值