React Context 是道具钻孔的解药吗? [英] Is React Context an antidote for prop drilling?

查看:35
本文介绍了React Context 是道具钻孔的解药吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果 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 并定义 nameage,那么我们必须设置一个提供程序来提供消费信息的是孩子.

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>
 )
}

nameage 是我们想要向我们的孩子公开的值,在这种情况下,我们只有一个孩子 Profile.现在我们可以通过从上下文中解构它们来访问 Profile 中的 nameage.

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 组件以实际更新 nameage 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆