我的 useContext 组件如何知道获取 App.js 中的值?
How does my useContext component know to get the value in App.js?
我正在学习教程,它看起来像这样:
App.js
import React from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Index } from './pages/index';
import { About } from './pages/about/about';
import { UserContext } from './UserContext';
function AppRouter() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to='/'> Home</Link>
</li>
<li>
<Link to='/about'>About</Link>
</li>
</ul>
</nav>
<UserContext.Provider value='hello from context'>
<Route path='/' exact component={Index} />
<Route path='/about/' component={About} />
</UserContext.Provider>
</div>
</Router>
);
}
export default AppRouter;
UserContext.js
import {createContext} from 'react'
export const UserContext = createContext(null);
index.js
import React, { useContext } from 'react';
import { UserContext } from '../UserContext';
export function Index() {
const msg= useContext(UserContext);
return (
<div>
<h2>Home</h2>;
<div>{msg}</div>;
</div>
);
}
当我 运行 这个 React 应用程序时,{msg} 变成 App.js
文件中的 hello from context
。
我不明白的是,当我查看 index.js
时,它仅从 UserContext.js
导入,它怎么知道 value
在 App.js
文件?在我看来,如果我还导入了 App.js
文件,它只会看到。但是 React 应用程序只知道在哪里可以找到它。答案是,当 index.js
导入 UserContext
时,应用程序会四处查看以查看从其他地方导入 UserContext.js
,然后根据它看到的所有内容构建 React 应用程序的输出?我觉得我错过了很大一部分反应应用程序,这些应用程序会让我更清楚。
如果不揭开 React 框架、ReactDOM 和 Fiber 的面纱,可能最容易想到 React Context API as an optimized version of the Lifting State Up 模式。
并不是 React 正在抓取您所有的导入等来确定使用了哪些文件,而是在您编写所有文件时生成的 DOM(React 的 VirtualDOM)组成您的应用程序的组件。您使用 JSX 来描述 UI 结构。
我们将从举升状态示例开始。
const Child1 = ({ value }) => <div>{value}</div>;
const Child2 = ({ setValue }) => <button onClick={() => setValue(42)}>Update</button>;
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<>
<Child1 value={value} />
<Child2 setValue={setValue} />
</>
);
};
这里我们有一个以 Parent
作为根节点和两个叶节点 Child1
和 Child2
的树。请注意,Child1
不知道也不关心 value
来自哪里或如何更新,它只是接收一个 prop。同样,Child2
不知道也不关心什么正在消耗它正在更新的值。
我们会将状态提升一个级别并添加一个中间组件。
const IntermediateComponent1 = (props) => (
<div>
<h1>I'm an intermediate child component</h1>
<Child1 value={props.value} />
</div>
);
const IntermediateComponent2 = (props) => (
<div>
<h1>I'm another intermediate child component</h1>
<Child2 setValue={props.setValue} />
</div>
);
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<>
<IntermediateComponent1 value={value} />
<IntermediateComponent2 setValue={setValue} />
</>
);
};
您现在应该注意到两件事:
- Child 1 和 2 相距较远,但一般的 DOM 结构允许数据从单个位置流出并被 children 更向下的树使用。
- 中间组件需要知道它们需要代理到其后代的道具(issue/pattern 称为“props-drilling”)。
React 上下文 API 是一种做同样事情的方法,但不需要显式传递 (drill) 道具通过所有中间 children .上下文提供者是根节点,它提供了一个值,供 children 在树的更下方使用。
const Child1 = () => {
const { value } = useContext(MyContext); // <-- "value" out
return <div>{value}</div>;
};
const Child2 = () => {
const { setValue } = useContext(MyContext); // <-- "setValue" out
return <button onClick={() => setValue(42)}>Update</button>
};
const IntermediateComponent1 = () => (
<div>
<h1>I'm an intermediate child component</h1>
<Child1 />
</div>
);
const IntermediateComponent2 = () => (
<div>
<h1>I'm another intermediate child component</h1>
<Child2 />
</div>
);
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<MyContext.Provider value={{ value, setValue }}> // <-- "value" in
<IntermediateComponent1 />
<IntermediateComponent2 />
</MyContext.Provider>
);
};
现在,希望您可以了解后代如何通过生成的 DOM 树结构使用从上下文提供的值。使用上下文时,children 将访问最接近的上下文提供者的上下文值 以上 它们在树中。也就是说,最近的祖先 Provider 组件。
我正在学习教程,它看起来像这样:
App.js
import React from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Index } from './pages/index';
import { About } from './pages/about/about';
import { UserContext } from './UserContext';
function AppRouter() {
return (
<Router>
<div>
<nav>
<ul>
<li>
<Link to='/'> Home</Link>
</li>
<li>
<Link to='/about'>About</Link>
</li>
</ul>
</nav>
<UserContext.Provider value='hello from context'>
<Route path='/' exact component={Index} />
<Route path='/about/' component={About} />
</UserContext.Provider>
</div>
</Router>
);
}
export default AppRouter;
UserContext.js
import {createContext} from 'react'
export const UserContext = createContext(null);
index.js
import React, { useContext } from 'react';
import { UserContext } from '../UserContext';
export function Index() {
const msg= useContext(UserContext);
return (
<div>
<h2>Home</h2>;
<div>{msg}</div>;
</div>
);
}
当我 运行 这个 React 应用程序时,{msg} 变成 App.js
文件中的 hello from context
。
我不明白的是,当我查看 index.js
时,它仅从 UserContext.js
导入,它怎么知道 value
在 App.js
文件?在我看来,如果我还导入了 App.js
文件,它只会看到。但是 React 应用程序只知道在哪里可以找到它。答案是,当 index.js
导入 UserContext
时,应用程序会四处查看以查看从其他地方导入 UserContext.js
,然后根据它看到的所有内容构建 React 应用程序的输出?我觉得我错过了很大一部分反应应用程序,这些应用程序会让我更清楚。
如果不揭开 React 框架、ReactDOM 和 Fiber 的面纱,可能最容易想到 React Context API as an optimized version of the Lifting State Up 模式。
并不是 React 正在抓取您所有的导入等来确定使用了哪些文件,而是在您编写所有文件时生成的 DOM(React 的 VirtualDOM)组成您的应用程序的组件。您使用 JSX 来描述 UI 结构。
我们将从举升状态示例开始。
const Child1 = ({ value }) => <div>{value}</div>;
const Child2 = ({ setValue }) => <button onClick={() => setValue(42)}>Update</button>;
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<>
<Child1 value={value} />
<Child2 setValue={setValue} />
</>
);
};
这里我们有一个以 Parent
作为根节点和两个叶节点 Child1
和 Child2
的树。请注意,Child1
不知道也不关心 value
来自哪里或如何更新,它只是接收一个 prop。同样,Child2
不知道也不关心什么正在消耗它正在更新的值。
我们会将状态提升一个级别并添加一个中间组件。
const IntermediateComponent1 = (props) => (
<div>
<h1>I'm an intermediate child component</h1>
<Child1 value={props.value} />
</div>
);
const IntermediateComponent2 = (props) => (
<div>
<h1>I'm another intermediate child component</h1>
<Child2 setValue={props.setValue} />
</div>
);
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<>
<IntermediateComponent1 value={value} />
<IntermediateComponent2 setValue={setValue} />
</>
);
};
您现在应该注意到两件事:
- Child 1 和 2 相距较远,但一般的 DOM 结构允许数据从单个位置流出并被 children 更向下的树使用。
- 中间组件需要知道它们需要代理到其后代的道具(issue/pattern 称为“props-drilling”)。
React 上下文 API 是一种做同样事情的方法,但不需要显式传递 (drill) 道具通过所有中间 children .上下文提供者是根节点,它提供了一个值,供 children 在树的更下方使用。
const Child1 = () => {
const { value } = useContext(MyContext); // <-- "value" out
return <div>{value}</div>;
};
const Child2 = () => {
const { setValue } = useContext(MyContext); // <-- "setValue" out
return <button onClick={() => setValue(42)}>Update</button>
};
const IntermediateComponent1 = () => (
<div>
<h1>I'm an intermediate child component</h1>
<Child1 />
</div>
);
const IntermediateComponent2 = () => (
<div>
<h1>I'm another intermediate child component</h1>
<Child2 />
</div>
);
const Parent = () => {
const [value, setValue] = React.useState(0);
return (
<MyContext.Provider value={{ value, setValue }}> // <-- "value" in
<IntermediateComponent1 />
<IntermediateComponent2 />
</MyContext.Provider>
);
};
现在,希望您可以了解后代如何通过生成的 DOM 树结构使用从上下文提供的值。使用上下文时,children 将访问最接近的上下文提供者的上下文值 以上 它们在树中。也就是说,最近的祖先 Provider 组件。