reactjs - 防止componentDidUpdate的函数包装器?
问题描述
我有一个组件 FancySpanComponent:
class FancySpanComponent extends React.Component {
render() {
return (
<span ref={this.props.innerRef} className={this.props.className }>
<div style={{ textAlign: "center" }}>rand: {this.props.randomData}</div>
</span>
);
}
}
我将其放入记录器包装器 PropsLogger 中,并且该包装器是通过 React.forwardRef() 创建的,因此我的主容器可以使用 FancySpanComponent 中的跨度(我正在学习 React 并测试我可以测试的任何情况,所以请不要判断^^'):
class PropsLogger extends React.Component {
componentDidMount() {
console.log("(Logger) mounting");
}
componentDidUpdate(prevProps) {
console.log("(Logger) Previous:", prevProps);
console.log("(Logger) New:", this.props);
}
render() { return <FancySpanComponent innerRef={this.props.innerRef} {...this.props} />; }
}
const FancySpan = React.forwardRef((props, ref) => <PropsLogger innerRef={ref} {...props} />);
它工作得非常好:当一个道具发生变化时,一切都会重新渲染,新旧道具都渴望进入控制台。但是,如果我想让该包装器更灵活并适用于任何组件,我必须将自己包装到一个函数中,以便我可以传递子类名称并在记录器的 render() 函数中创建它(这个例子来自 reactjs .org 文档):
function propsLoggerWrapper(ClassToLog, props, ref) {
class PropsLogger extends React.Component {
componentDidMount() {...}
componentDidUpdate(prevProps) {...}
render() { return <ClassToLog innerRef={ref} {...props} />; }
}
return <PropsLogger />;
};
const FancySpan = React.forwardRef((props, ref) => propsLoggerWrapper(FancySpanComponent, props, ref));
在这种情况下,问题是每次道具更改时,我不知道为什么,但我的记录器包装器及其子级在技术上没有更新:它们被卸载并重新安装,因此记录器 componentDidUpdate() 永远不会被触发。您是否知道为什么在该函数调用的情况下会发生这种情况?
非常感谢您提前。
解决方案
试试这个方法。您尝试的 HoC 方法似乎不正确。
您必须从函数内部返回一个类。这样它就可以像 React 组件一样使用。
function propsLoggerWrapper(ClassToLog) {
return class extends React.Component {
componentDidMount() {}
componentDidUpdate(prevProps) {}
render() {
return <ClassToLog {...this.props} ref={this.props.innerRef} />;
}
};
const LoggedSpan = propsLoggerWrapper(Span);
const LoggedSpanWithRef = React.forwardRef((props, ref) => (
<LoggedSpan innerRef={ref} {...props} />
));
然后像这样使用它,创建spanRef
自己。
<LoggedSpanWithRef ref={this.spanRef} someprop={1} />
检查此代码沙箱以获取工作示例
推荐阅读
- python - 如何在我的自定义小部件模板中包含内置的 django 小部件模板?
- java - 为什么 list.parallelStream().forEach() 不处理 Java 中列表中的所有元素?
- python - 如何区分 OpenCV 中的实心圆/轮廓和空心圆/轮廓?
- flutter - 按下按钮时如何增加文本的大小?
- javascript - 未捕获的类型错误:无法读取 jquery 中未定义的属性“SPAN_ID”
- c++ - ProtoBuf:如何为新消息重用 FieldDescriptor?如何有效地从动态消息中获取字段值?
- fortran - LAPACK DGETRF+DGETRI 失败
- sql - SQL - 每 00 小时重置一次序列
- linux - vscode python调试器不工作:连接被拒绝
- youtube-api - 无法从此频道“UCDtoxgCJVoKp_ImQqWTuUpw”获取视频