是否有系统的方法来调试导致组件在React中重新呈现的原因?我放了一个简单的console.log()来查看它呈现了多少时间,但我很难弄清楚是什么原因导致组件呈现多次,即(4次)在我的情况下。是否有一个工具可以显示时间轴和/或所有组件树的渲染和顺序?
当前回答
如果你想要一个没有任何外部依赖的简短片段,我发现这很有用
componentDidUpdate(prevProps, prevState) {
Object.entries(this.props).forEach(([key, val]) =>
prevProps[key] !== val && console.log(`Prop '${key}' changed`)
);
if (this.state) {
Object.entries(this.state).forEach(([key, val]) =>
prevState[key] !== val && console.log(`State '${key}' changed`)
);
}
}
下面是我用来跟踪函数组件更新的一个小钩子
function useTraceUpdate(props) {
const prev = useRef(props);
useEffect(() => {
const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
if (prev.current[k] !== v) {
ps[k] = [prev.current[k], v];
}
return ps;
}, {});
if (Object.keys(changedProps).length > 0) {
console.log('Changed props:', changedProps);
}
prev.current = props;
});
}
// Usage
function MyComponent(props) {
useTraceUpdate(props);
return <div>{props.children}</div>;
}
其他回答
下面是React组件将重新渲染的一些实例。
Parent component rerender Calling this.setState() within the component. This will trigger the following component lifecycle methods shouldComponentUpdate > componentWillUpdate > render > componentDidUpdate Changes in component's props. This will trigger componentWillReceiveProps > shouldComponentUpdate > componentWillUpdate > render > componentDidUpdate (connect method of react-redux trigger this when there are applicable changes in the Redux store) calling this.forceUpdate which is similar to this.setState
您可以通过在shouldComponentUpdate中实现检查来最小化组件的渲染器,如果不需要,则返回false。
另一种方法是使用React。PureComponent或无状态组件。纯的和无状态的组件只有在它的道具发生变化时才会重新渲染。
你可以使用React Devtools profiler工具检查组件(重新)渲染的原因。不需要更改代码。请参阅react团队的博客文章介绍react分析器。
首先,转到设置cog > profiler,并选择“记录每个组件渲染的原因”
上面的答案非常有用,如果有人正在寻找一种特定的方法来检测重新渲染的原因,那么我发现这个库redux-logger非常有用。
你能做的就是添加库并启用状态差异(它在文档中),如下所示:
const logger = createLogger({
diff: true,
});
并在存储中添加中间件。
然后在要测试的组件的渲染函数中放入console.log()。
然后,您可以运行应用程序并检查控制台日志。无论在哪里有一个日志之前,它都会显示状态(nextProps和this.props)之间的差异,你可以决定是否真的需要渲染
它将类似于上面的图像连同diff键。
奇怪的是没有人给出这个答案,但我发现它非常有用,特别是因为道具的变化几乎总是深嵌套的。
钩子粉丝:
import deep_diff from "deep-diff";
const withPropsChecker = WrappedComponent => {
return props => {
const prevProps = useRef(props);
useEffect(() => {
const diff = deep_diff.diff(prevProps.current, props);
if (diff) {
console.log(diff);
}
prevProps.current = props;
});
return <WrappedComponent {...props} />;
};
};
“老”平衡粉丝:
import deep_diff from "deep-diff";
componentDidUpdate(prevProps, prevState) {
const diff = deep_diff.diff(prevProps, this.props);
if (diff) {
console.log(diff);
}
}
附注:我仍然更喜欢使用HOC(高阶组件),因为有时你在顶部解构了你的道具,Jacob的解决方案不太适合
免责声明:与包所有者没有任何联系。只是点击数十次,试图找出深嵌套对象之间的差异,这是一种痛苦。
如果你想要一个没有任何外部依赖的简短片段,我发现这很有用
componentDidUpdate(prevProps, prevState) {
Object.entries(this.props).forEach(([key, val]) =>
prevProps[key] !== val && console.log(`Prop '${key}' changed`)
);
if (this.state) {
Object.entries(this.state).forEach(([key, val]) =>
prevState[key] !== val && console.log(`State '${key}' changed`)
);
}
}
下面是我用来跟踪函数组件更新的一个小钩子
function useTraceUpdate(props) {
const prev = useRef(props);
useEffect(() => {
const changedProps = Object.entries(props).reduce((ps, [k, v]) => {
if (prev.current[k] !== v) {
ps[k] = [prev.current[k], v];
}
return ps;
}, {});
if (Object.keys(changedProps).length > 0) {
console.log('Changed props:', changedProps);
}
prev.current = props;
});
}
// Usage
function MyComponent(props) {
useTraceUpdate(props);
return <div>{props.children}</div>;
}
推荐文章
- React: 'Redirect'没有从' React -router-dom'中导出
- 如何在React中使用钩子强制组件重新渲染?
- React组件中使用TypeScript的默认属性值
- 反应钩子-正确的方式清除超时和间隔
- 在React.js中正确的img路径
- 在React.js中更新组件onScroll的样式
- onClick ReactJS调用多个函数
- 为什么React 16中的Fragments比容器div更好?
- 在Redux应用程序中哪里写localStorage ?
- 如何在ReactJS中验证嵌套对象的PropTypes ?
- 如何在ReactJS中从“外部”访问组件方法?
- 'React'指的是一个UMD全局,但当前文件是一个模块
- 为什么useState不触发重新渲染?
- 如何使用回调与useState挂钩在反应
- 如何包括引导css和js在reactjs应用程序?