为啥我不能在组件道具中使用内联函数?可以举个例子详细解释一下吗?失去所有状态是啥意思?
Posted
技术标签:
【中文标题】为啥我不能在组件道具中使用内联函数?可以举个例子详细解释一下吗?失去所有状态是啥意思?【英文标题】:Why I can not use inline function in component prop? Can you explain in detail by giving an example? What means saying losing all state?为什么我不能在组件道具中使用内联函数?可以举个例子详细解释一下吗?失去所有状态是什么意思? 【发布时间】:2021-12-01 09:27:24 【问题描述】:注意:component 属性接受组件,而不是渲染函数。不要传递内联函数(例如 component=() => ),否则当父组件重新渲染时,您的组件将卸载并重新安装丢失所有状态。请参阅传递其他道具以获取替代方案。
来自模拟器的警告。 enter image description here
function HomeScreen(props: Object)
return (
<Navigator initialRouteName="Empty1">
<Screen
name="Empty1"
component=() =>
return (
<View>
<Text>Example Text</Text>
</View>
);
/>
<Screen name="Home1" component=HomeScreen1 />
</Navigator>
);
【问题讨论】:
“失去所有状态是什么意思?”你知道在 React 应用程序的上下文中什么是“状态”吗?因为如果没有,我建议从basic tutorials开始。 感谢您的建议。 【参考方案1】:它警告您每次重新渲染屏幕时都会重新渲染组件。这是因为每次评估组件 arg 时,它都会返回一个新的内联函数。 (道具每次都会改变,因此它必须总是重新渲染)
对同一个内联函数求值两次会产生不同的对象。 例如。
let funcs = []
for (let i =0 ; i<2; i++)
funcs.push(() => 1)
funcs[0] == funcs[1]
>>> false
您可以包装 this is useCallback 以获得仅在需要时更新的稳定函数(在您的情况下永远不会,因为它不捕获任何状态)。 More on hooks here
function HomeScreen(props: Object)
let component = useCallback(() =>
return (
<View>
<Text>Example Text</Text>
</View>
);
, [] // no dependencies. This lambda will only be evaluated once.
);
return (
<Navigator initialRouteName="Empty1">
<Screen
name="Empty1"
component=component
/>
<Screen name="Home1" component=HomeScreen1 />
</Navigator>
);
或者由于这个函数不依赖于任何有状态的东西,你也可以在这个文件的顶部全局声明它。
let component = () =>
return (
<View>
<Text>Example Text</Text>
</View>
);
;
function HomeScreen(props: Object)
return (
<Navigator initialRouteName="Empty1">
<Screen
name="Empty1"
component=component
/>
<Screen name="Home1" component=HomeScreen1 />
</Navigator>
);
【讨论】:
【参考方案2】:你需要了解隐藏在 JSX 语法背后的东西。
当你使用<SomeComponent/>
时,它会被添加到 React 虚拟 DOM 并一直存在,直到树发生变化并且必须卸载组件。它在重新渲染后仍然存在,DOM 正在更新,但组件仍然存在。
当您使用() => <SomeComponent />
时,此组件在每次重新渲染父组件时都是一个新对象。如果它有状态(通过 setState 钩子),它将被重新初始化。如果它在useEffect(() => , [])
钩子中有一些代码,它将被再次调用。
【讨论】:
以上是关于为啥我不能在组件道具中使用内联函数?可以举个例子详细解释一下吗?失去所有状态是啥意思?的主要内容,如果未能解决你的问题,请参考以下文章
当组件中有解构赋值时,为啥默认道具不能防止 TypeError?