假设我们有一个父组件和多个功能子组件。我想清楚地知道父级是否重新渲染,子级是否重新渲染。
在阅读了几篇文章后,我了解到我们可以通过 3 种方法来检测重新渲染。(如果还有更多方法,请告诉我。)
1. 将 a 放入console.log子组件中。
2.在设置中使用Chrome油漆闪烁选项。
3.使用React开发工具
所有这些方法都可以正确地了解组件是否真的重新渲染吗?因为它似乎不能与 React.memo 一起正常工作。
console.log当我用 React.memo 包装子组件时,当父组件重新渲染时,它不会打印,这是正确的。但仍然使用 Chrome 和 React 开发工具突出显示子组件,就像它重新渲染一样。
CodeSandbox: https: //codesandbox.io/s/bold-cloud-iv0rv (如果我们添加一辆新车,静态组件仍然以绿色突出显示,但根据备忘录,它不应该重新渲染。)
现在我怀疑,油漆闪烁是否无法正常工作或 React.memo 有问题?
我在 flatlist 的页脚中放置了一个输入字段,但是当我尝试输入任何内容时,它会自动关闭键盘,因为重新渲染了 flatlist 页脚。
我试图从 Scrollview 嵌套 flatlist 但这带来了警告..
如何阻止页脚被重新渲染?我可以在不嵌套 Scrollview 的 flatlist 的情况下解决这个问题吗?
<FlatList
ListHeaderComponent={() => (
<View style={styles.discountContainer}>
<Text style={[styles.buttonText, { letterSpacing: 3 }]}>
10% DISCOUNT ON 8 COURSES
</Text>
</View>
)}
numColumns={2}
data={data}
renderItem={({ item }) => (
<View>
<SingleProduct item={item} />
</View>
)}
ListFooterComponent={() => (
<View>
<View style={styles.couponContainer}>
<Input
placeholder='Coupon code'
placeholderTextColor='#0a5796'
color='#0a5796'
inputStyle={{
color: '#0a5796',
}}
inputContainerStyle={{
borderBottomWidth: 0,
height: 50,
}}
containerStyle={styles.couponInputContainer}
onChangeText={(value) =>
this.setState({ couponCode: value })
}
value={this.state.couponCode}
/>
{couponLoading …Run Code Online (Sandbox Code Playgroud) 我认为事实是,当父组件在 React 中重新渲染时,通常所有子组件也会重新渲染。
我做了一个实验来证实:
https://codesandbox.io/s/currying-pine-r16rzi
return (
<div>
<div>Time now is {timeNow.toLocaleTimeString()}</div>
<TheTimeNow /><TheTimeNow />
</div>
);
Run Code Online (Sandbox Code Playgroud)
该父组件重新渲染,并且<TheTimeNow />props 值没有变化(它没有),但它仍然重新渲染并显示更新时间。
我认为React实际上改变了DOM是不一样的,因为我认为其机制是React使用以前的虚拟DOM与新的虚拟DOM进行比较,并根据需要仅更新最小的实际DOM节点document.documentElement。
如果您使用 Google Chrome 并在时间语句上执行 Inspect Element,就可以看到这一点:只有时间部分发生变化,其他英文单词保持不变。与此相比,如果是纯 JavaScript,则所有节点都会发生变化: https: //jsfiddle.net/8sj2ugae/1/,当您执行 Inspect Element 时。
然而,我们不能说,如果一个孩子是<Foo />并且由于没有传递给它的道具,那么<Foo />真的不应该改变,并且调用是浪费的Foo()?(如果Foo是函数组件,或者render()如果是类组件则调用该方法。)
现在,由于所有子项都会重新渲染,这意味着它们的所有子项也会重新渲染。递归地重复这个规则,这意味着整个子树被重新渲染。
我的问题是:如果他们的道具没有改变,他们是否真的不需要重新渲染,或者是否有其他因素使他们真的需要重新渲染?
我在我的应用程序中使用React Navigation。返回时如何刷新上一个面板上的数据?
一个实际的例子是:我目前在面板A中,导航到面板B,在其中更新面板A中显示的数据库中的数据。在更改数据库中的数据之后,我对面板A进行goBack()之后,希望面板A现在已重新呈现并保存数据库中的新数据。
我已经读到可以将自定义刷新函数作为参数传递给子类,然后在返回之前调用它,但是我认为这不是实现我想要的方法的一种好方法,因为我更新了尚未安装的组件并且会抛出一个错误。
我在 Vue 路由器中的路线:
{ path: 'articles/create', component: () => import('Detail.vue') },
{ path: 'articles/:id/edit', component: () => import('Detail.vue') },
Run Code Online (Sandbox Code Playgroud)
如您所见,我Detail.vue在两条路线上渲染相同的 Vue 组件。
当 URL从例如变为时,如何“强制”Vue 销毁并重新创建Detail.vue组件?/articles/5/edit/articles/create
我有以下代码(CodeSandbox):
function App() {
const [blah, setBlah] = useState(true);
console.log('BLAH', blah);
setBlah(true);
return <button onClick={() => setBlah(true)}>Blah</button>;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,setBlah(true)组件的顶层导致了太多的重新渲染。我不明白的是,如果您注释掉顶层setBlah(true)并开始混合“Blah”按钮,为什么该组件不会重新渲染?两者都一遍又一遍地将 的状态设置blah为 true,但只有顶层setBlah(true)会导致重新渲染。
来自React 文档关于退出状态更新:“请注意,React 可能仍需要在退出之前再次渲染该特定组件。” 这里的关键词是“可能”,对我来说这意味着根据文档我的情况是有效的。所以问题可能会变成,在什么条件下setState,使用已设置的相同值调用 会导致重新渲染?了解这一点很有用,因为人们可能希望在setState方法前面放置逻辑来检查该值是否与当前值相同,以免导致错误的重新渲染。
有人请用一个简单的例子向我解释 React 文档的最后一段,它是关于 React.PureComponent 的,我见过的所有示例都是高级的,我刚刚开始了解这个概念,但我无法确切地看到它是什么指。正是这一点,孩子也应该“纯洁”。据我所知,我认为这种说法有些言过其实,因为如果父亲不重新呈现自己,那么孩子们也不会重新呈现自己。,或者,是否有什么东西我无法逃脱而我无法想象?这就是为什么我需要一个简单的例子,我已经在这里查看了所有类似的问题,但它们是高级示例,并不涵盖我正在寻找的内容。
“此外,React.PureComponent 的 shouldComponentUpdate() 会跳过整个组件子树的 prop 更新。确保所有子组件也是“纯”的”
现在有了钩子,我已经将组件的状态分成了更微型的状态。这看起来更好,直到我想找出是什么状态变化导致了特定的重新渲染。
如何轻松找出导致特定重新渲染的状态变化?
我正在尝试创建一个基于useContext 的自定义挂钩useFocus以仅将焦点设置在我选择的组件上。它的工作,但其他组件正在呈现,即使我使用useCallback作为我的 useFocus 自定义挂钩返回的函数。
我只想重新渲染焦点变化的组件。
我知道如果代码很快,重新渲染可能是一个小问题,但我不明白为什么要重新渲染。你能给我一些解释或解决办法吗?
预期结果:
单击“设置焦点”按钮时,我期望得到:
1 个 A/B/D 渲染
2 个 C/E 渲染
谢谢。
这是我的代码:
import React, { createContext, useCallback, useContext, useState } from "react";
import "./styles.css";
const StepContext = createContext({});
//This is just to display number or render for each Items
function useRenderCounter() {
const ref = React.useRef();
React.useEffect(() => {
ref.current.textContent = Number(ref.current.textContent || "0") + 1;
});
return (
<span
style={{
backgroundColor: "#ccc",
borderRadius: 4,
padding: "2px 4px", …Run Code Online (Sandbox Code Playgroud) 我在反应测试库中使用 rerender 和 renderHook 。最近将 React 版本升级到 18。在其中一个测试用例中出现以下错误。
console.error 警告:ReactDOM.render 在 React 18 中不再支持。请改用 createRoot。在您切换到新 API 之前,您的应用程序的行为就像运行 React 17 一样。了解更多信息:https ://reactjs.org/link/switch-to-createroot
重新渲染();renderHook(() => abc());
因为,我不使用渲染,为什么警告将重新渲染和 renderHook 指向渲染。
您能指出如何进一步挖掘这个问题吗?
rerender ×10
reactjs ×7
react-hooks ×4
javascript ×2
react-native ×2
components ×1
footer ×1
react-18 ×1
react-props ×1
refresh ×1
render ×1
state ×1
use-context ×1
usecallback ×1
virtual-dom ×1
vue.js ×1