Skip to content

Context

在使用 Context 之前可以考虑的替代方案
tsx
import { useState } from "react";

function Button({
    theme,
    toggleTheme,
}: {
    theme: string;
    toggleTheme: () => void;
}) {
    return (
        <>
            <p>{theme}</p>
            <button onClick={toggleTheme}>Toggle Theme Through Props</button>
        </>
    );
}

function Card({
    theme,
    toggleTheme,
}: {
    theme: string;
    toggleTheme: () => void;
}) {
    const cardStyle = {
        borderRadius: "8px",
        boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
    };

    return (
        <div style={cardStyle}>
            <Button theme={theme} toggleTheme={toggleTheme} />
        </div>
    );
}

export default function ContextReplaceWithProps() {
    const [theme, setTheme] = useState("light");

    function toggleTheme() {
        setTheme(theme === "light" ? "dark" : "light");
    }

    return (
        <>
            <Card theme={theme} toggleTheme={toggleTheme} />
        </>
    );
}
tsx
import { useState } from "react";

function Button({
    theme,
    toggleTheme,
}: {
    theme: string;
    toggleTheme: () => void;
}) {
    return (
        <>
            <p>{theme}</p>
            <button onClick={toggleTheme}>Toggle Theme Through Children</button>
        </>
    );
}

function Card({ children }: { children: React.ReactNode }) {
    const cardStyle = {
        borderRadius: "8px",
        boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
    };

    return <div style={cardStyle}>{children}</div>;
}

export default function ContextReplaceWithChildren() {
    const [theme, setTheme] = useState("light");

    function toggleTheme() {
        setTheme(theme === "light" ? "dark" : "light");
    }

    return (
        <>
            <Card>
                <Button theme={theme} toggleTheme={toggleTheme} />
            </Card>
        </>
    );
}

什么是 Context

Context 是 React 中提供的可以在组件树中直接传递数据而无需逐层传递 Props 的功能。

基本用法

  • 首先通过createContext方法创建一个 Context 对象
  • 然后通过Context.Provider组件提供一个共享的值
  • 最后通过Context.Consumer组件消费这个共享的值
ts
import { createContext } from "react";

export const ContextTheme = createContext({
    theme: "light",
    toggleTheme: () => { },
});
tsx
import { useState } from "react";
import { ContextTheme } from "./ContextTheme";
import Button from "./ContextBasicConsumer";

function Card() {
    const cardStyle = {
        borderRadius: "8px",
        boxShadow: "0 2px 8px rgba(0,0,0,0.1)",
    };

    return (
        <div style={cardStyle}>
            <Button />
        </div>
    );
}

export default function ContextBasicProvider() {
    const [theme, setTheme] = useState("light");

    function toggleTheme() {
        setTheme(theme === "light" ? "dark" : "light");
    }

    return (
        <ContextTheme.Provider value={{ theme, toggleTheme }}>
            <Card />
        </ContextTheme.Provider>
    );
}
tsx
import { ContextTheme } from "./ContextTheme";

export default function Button() {
    return (
        <ContextTheme.Consumer>
            {({ theme, toggleTheme }) => (
                <>
                    <p>{theme}</p>
                    <button onClick={toggleTheme}>
                        Toggle Theme Through Context
                    </button>
                </>
            )}
        </ContextTheme.Consumer>
    );
}