React Context 是道具钻探的解毒剂吗?
Posted
技术标签:
【中文标题】React Context 是道具钻探的解毒剂吗?【英文标题】:Is React Context an antidote for prop drilling? 【发布时间】:2020-11-10 20:44:11 【问题描述】:如果 React Context API 旨在用于传递全局变量,我们为什么要使用它们来代替从父组件到子组件的传递道具(道具钻探)?由于大多数传递的道具并不意味着在应用程序范围内(即全局)可用。
【问题讨论】:
【参考方案1】:上下文中定义的变量或值可用于任何试图解构这些值的组件。但是,如果您有任何设置器更改了这些定义的值,则只有传递给 Provider
的子级将获得更新的值。
例如,如果我们创建一个上下文 myContext
并定义 name
和 age
,那么我们必须设置一个提供程序,为其子项提供要使用的信息。
const myContext = createContext(
name: 'Bob',
age: 35
);
现在,我们可以使用 Provider 将这些数据传递给孩子。
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
。
function Profile()
const name, age = useContext(myContext)
return (
<ul>
<li>name</li>
<li>age</li>
</ul>
)
但是假设在我们项目的其他地方,我们有一个名为 Foo
的组件,我们想要访问 name
。
function Foo()
const name = useContext(myContext) // you will only receive the default values defined in context
return <p>name</p>
这将返回myContext
中定义的默认“Bob”。你可能会想,那有什么意义呢?
如果我们更新我们的HelloWorld
组件以实际更新name
和age
onMount,Foo
仍将显示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
)
当您有需要传递数据和设置器而不是道具钻探的孤立功能或组件时,这非常有用。您可以让一个组件使用多个上下文,并且您可以拥有任意数量的上下文,只要它们有意义。如果您只传递一次道具,则使用上下文没有意义。如果你有更复杂的道具传递,上下文可能是值得的。
【讨论】:
【参考方案2】:新的 react context api 允许你“限定”值,你不必用上下文提供者来包装你的整个应用程序,你可以只包装组件树中你需要特定 props 的部分。当您的组件树嵌套很深并且您需要将某些道具传递多个级别时,它会很有用。
【讨论】:
【参考方案3】:在大多数情况下,更改组件上的 props 会导致它重新渲染。道具钻孔会减慢您的应用程序并降低其可读性。
【讨论】:
Array.splice() 会修改父数组,而 Array.slice() 不会。 不是数字 (NaN) 也是数字。以上是关于React Context 是道具钻探的解毒剂吗?的主要内容,如果未能解决你的问题,请参考以下文章
React Context API,从子组件设置上下文状态,而不是将函数作为道具传递
除了 value 道具之外的任何道具都可以在 Context.Provider 中工作吗
React.js。在函数体中创建带参数(和道具将是参数)或引用道具的方法更好吗?