Reactjs React-父组件的装载早于子组件
到目前为止,我一直认为生命周期是这样工作的:Reactjs React-父组件的装载早于子组件,reactjs,Reactjs,到目前为止,我一直认为生命周期是这样工作的: <ComponentA> <ComponentB /> </ComponentA> 组件A(组件将安装) 1.1。组件B(组件将安装) 1.2:组件B(组件D安装) ComponentA(componentDidMount) 因此,为了完成DidMount状态,父级总是必须等待子级被呈现 然而,我发现在我拥有的复杂组件上,这种情况并没有发生 它呼吁: 组件A(组件将安装) ComponentA(compo
<ComponentA>
<ComponentB />
</ComponentA>
如果ComponentA在没有呈现子组件(ComponentB)的情况下呈现,那么DOM中应该是什么呢?我很好奇,所以我把
var Container=React.createClass({
componentWillMount:function(){
返回console.log(“容器将装载”);
},
componentDidMount:function(){
返回console.log(“容器未装载”);
},
render:function(){
返回{this.props.children};
}
});
var Child=React.createClass({
componentWillMount:function(){
返回console.log(“子级将挂载”);
},
componentDidMount:function(){
返回console.log(“Child-did-mount”);
},
render:function(){
返回你好世界;
}
});
ReactDOM.render(
,
document.getElementById('容器')
);
这将产生输出
容器将安装
孩子会爬上去的
这孩子上了山
集装箱确实装上了
这符合你最初的期望
不确定这是否对您有帮助。经过艰苦的调试,我发现问题出在哪里: 我用了一个chilren组件 阅读我检查过的库的源代码,它的呈现会创建“WrappedComponent”或“占位符”。 因此,它创建了这个占位符,使该组件被认为是挂载的,而它仍然没有呈现我真正的孩子 在这里你可以看到:
/**
*因为我们需要在根节点上维护一个ref,该节点在我们的
*SizeMe组件我们需要将整个渲染包在一个子组件中。
*如果不这样做,则在从中删除占位符后,我们将丢失DOM引用
*渲染和实际组件将被渲染。
*我花了很长时间才弄明白,所以在这件事上要格外小心!
*/
常量RenderRapper=(WrappedComponent)=>{
功能尺寸测量仪(道具){
常数{
明确地说,
类名,
风格
大小,
禁用占位符,
…其他道具,
}=道具;
常数{宽度,高度}=大小;
const toRender=(宽度===未定义和高度===未定义和禁用占位符)
?
: ;
返回(
{toRender}
);
}
...
因此,我可以假设是的,生命周期顺序与我在第一个实例中假设的一样有效你能在JSFIDLE/codepen中重现这一点吗?别这么认为,代码太多了。这不是一个简单的示例代码,这就是为什么我提出了一般性问题,以确定这是否是预期的行为。抱歉:(从技术上讲,生命周期方法仅保证您的特定组件已安装。它不会对其子组件做出任何承诺。依赖此顺序通常表示您正在打破组件的封装边界。例如,如果您的组件呈现另一个组件,则该组件可能会选择加载数据时延迟渲染它的子项(即使它们是从上面传递的)。我很久以前就已经测试过了,以确保它能像那样工作。但无论如何,谢谢:)我已经找到了发生的情况!:)谢谢…遇到了同样的问题。看起来如果在sizeMe选项中传递noPlaceholder=true,它将首先渲染子项。
var Container = React.createClass({
componentWillMount: function() {
return console.log("Container will mount");
},
componentDidMount: function() {
return console.log("Container did mount");
},
render: function() {
return <div>{this.props.children}</div>;
}
});
var Child = React.createClass({
componentWillMount: function() {
return console.log("Child will mount");
},
componentDidMount: function() {
return console.log("Child did mount");
},
render: function() {
return <div> Hello World </div>;
}
});
ReactDOM.render(
<Container>
<Child />
</Container>,
document.getElementById('container')
);
/**
* As we need to maintain a ref on the root node that is rendered within our
* SizeMe component we need to wrap our entire render in a sub component.
* Without this, we lose the DOM ref after the placeholder is removed from
* the render and the actual component is rendered.
* It took me forever to figure this out, so tread extra careful on this one!
*/
const renderWrapper = (WrappedComponent) => {
function SizeMeRenderer(props) {
const {
explicitRef,
className,
style,
size,
disablePlaceholder,
...restProps,
} = props;
const { width, height } = size;
const toRender = (width === undefined && height === undefined && !disablePlaceholder)
? <Placeholder className={className} style={style} />
: <WrappedComponent className={className} style={style} size={size} {...restProps} />;
return (
<ReferenceWrapper ref={explicitRef}>
{toRender}
</ReferenceWrapper>
);
}
...