useContext 在幕后到底做了什么?

What exactly does useContext do behind the scenes?

大家好我是 React 新手。我试图使用 上下文 api 创建全局状态。我遇到了意想不到的事情。我学到的是,当创建上下文时,它有一个提供程序来包装那些需要数据的组件,当值发生变化时,提供程序将重新呈现所有包装的组件,对吗?

看看这个:

// AuthContext.js
export const AuthContext = createContext(null);

const AuthProvider = ({ children }) => {
        const [user, setUser] = useState({
            name: null,
        });

    return (
        <AuthContext.Provider value={{ user, setUser }}>
            {children}
        </AuthContext.Provider>
    );
};
// index.js
<AuthProvider>
    <App />
</AuthProvider>
// App.js
function App() {
    console.log("[App] ran");
    return (
        <>
            <Dashboard />
            <Login />
        </>
    );
}
// Dashboard.js
function Dashboard() {
    console.log("[Dashboard] ran");
    return <div>Dashboard</div>;
}
// Login.js
function Login() {
    console.log("[Login] ran");
    const { user, setUser } = useContext(AuthContext);
    const inputNameRef = useRef();

    return (
    <div>
        <input placeholder="Enter your name..." ref={inputNameRef} />
        <button
            onClick={() => {
            setUser(inputNameRef.current.value);
            }}
        >
        Submit
        </button>
    </div>
    );
}

当代码第一次运行时,输出为:

[App] ran

[Dashboard] ran

[Login] ran

并且当单击 提交按钮 时,将调用 setUser 函数并将新值设置为 AuthProvider 状态。提供者应该重新呈现所有组件,并且上面的输出应该再次被记录但是不,输出只是:

[Login] ran

我感兴趣的一点是,当我在仪表板组件中使用 useContext 时它起作用了,我的意思是该组件将被重新渲染。我认为它与 useContext 挂钩有关,但不知道它是如何工作的。引擎盖下发生了什么?

引用React官方关于Context的文档(https://reactjs.org/docs/context.html):

All consumers that are descendants of a Provider will re-render whenever the Provider’s value prop changes. The propagation from Provider to its descendant consumers (including .contextType and useContext) is not subject to the shouldComponentUpdate method, so the consumer is updated even when an ancestor component skips an update.

您可以将“消费者”视为其状态“消耗”useContext 挂钩的组件。也就是说,您只会在使用挂钩的组件中看到 re-render。这样,并不是上下文提供程序中的所有子项都会re-render在状态更改时被编辑,只有那些使用它的人。