React Context 是道具钻孔的解药吗? [英] Is React Context an antidote for prop drilling?
问题描述
如果 React Context API 旨在用于传递全局变量,为什么我们要使用它们来替代从父组件到子组件的传递道具(道具钻取)?由于大多数传递的 props 并不意味着在应用程序范围内可用,即全局可用.
If React Context API is meant to be used for passing global variables around, why should we use them to substitute passing props from parent to child components (prop drilling)? Since most props being passed are not meant to be available application-wide i.e globally.
推荐答案
上下文中定义的变量或值可用于任何试图解构这些值的组件.但是,如果您有任何更改这些定义值的 setter,则只有传递给 Provider
的子项才会获得更新的值.
The variables or values defined in context are available to any component that tries to destructure those values. However, if you have any setters that change those defined values, only the children that are passed to the Provider
will get the updated values.
例如,如果我们创建一个上下文 myContext
并定义 name
和 age
,那么我们必须设置一个提供程序来提供消费信息的是孩子.
For instance, if we create a context myContext
and define name
and age
, we have to then set up a provider that will provide it's children that information to consume.
const myContext = createContext({
name: 'Bob',
age: 35
});
现在,我们可以使用 Provider 将这些数据传递给孩子.
Now, we can use a Provider to pass that data down to children.
function HelloWorld() {
const { Provider } = myContext;
const [age, setAge] = useState(35)
const [name, setName] = useState('Bob')
return (
<Provider value={{ name, age }}>
<Profile />
</Provider>
)
}
name
和 age
是我们想要向我们的孩子公开的值,在这种情况下,我们只有一个孩子 Profile
.现在我们可以通过从上下文中解构它们来访问 Profile
中的 name
和 age
.
name
and age
are the values we want to expose to our children, in this case we just have one child Profile
. Now we can access name
and age
in Profile
by destructuring them from our context.
function Profile(){
const { name, age } = useContext(myContext)
return (
<ul>
<li>{name}</li>
<li>{age}</li>
</ul>
)
}
但是假设在我们项目的其他地方,我们有一个名为 Foo
的组件,我们想要访问 name
.
But let's say somewhere else in our project we have component called Foo
and we want to access name
.
function Foo() {
const { name } = useContext(myContext) // you will only receive the default values defined in context
return <p>{name}</p>
}
这将返回 myContext
中定义的默认Bob".你可能会想,这有什么意义?
This will return the default 'Bob' defined in myContext
. You may think, what was the point of that?
如果我们更新我们的 HelloWorld
组件以实际更新 name
和 age
onMount,Foo
仍然会显示鲍勃
.
If we update our HelloWorld
component to actually update the name
and age
onMount, Foo
will still show Bob
.
function HelloWorld() {
const { Provider } = myContext;
const [age, setAge] = useState("");
const [name, setName] = useState("");
useEffect(() => {
setAge(40);
setName("Bill");
}, []);
return (
<Provider value={{ name, age }}>
<Profile />
</Provider>
);
}
function Profile() {
return (
<ul>
<li>{name}</li> // returns Bill
<li>{age}</li> // returns 40
</ul>
)
}
function Foo() {
return (
<p>{name}</p> // returns Bob
)
}
当您有需要传递数据和 setter 而不是 prop 钻取的独立功能或组件时,这非常棒.您可以让一个组件使用多个上下文,并且您可以拥有任意数量的上下文,只要它们有意义即可.如果您只传递一次道具,则使用上下文没有意义.如果你有更复杂的道具传递,上下文可能是值得的.
This is great when you have isolated features or components that need to pass around data and setters instead of prop drilling. You can have a component consume multiple contexts and you can have as many contexts as you want as long as they make sense. If you are passing a prop down just once, does not make sense to use context. If you have more complex passing of props, context may be worth it.
这篇关于React Context 是道具钻孔的解药吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!