我有一个React应用程序。在我的应用中,我通常希望我的视图组件不要直接导入其他react组件。相反,我希望视图的父容器组件负责收集依赖项,并通过props将依赖项注入到视图中。
通常如下所示:
// Container.js
import SomeOtherComponent from '/somewhere'
import View from './View'
class Container extends React.Component {
render() {
return(
<View
component={<SomeOtherComponent/>}
/>
)
}
}
// View.js
const View = props => (
<div>
{props.component}
</div>
)
但是请注意,当作为道具传递给View时,SomeOtherComponent看起来是如何被实例化的。
这是否意味着在View之前实例化SomeOtherComponent(因此要经历所有相关的生命周期方法)?
或者SomeOtherComponent仅在实例化View并调用View的render方法时实例化吗?
答案 0 :(得分:2)
这取决于您“实例化”的意思。 <SomeOtherComponent/>
被转译为React.createElement(SomeOtherComponent, null)
,因此如果实例化意味着调用React.createElement,则它将在Container的渲染期间发生。
但是,我认为这不是一件非常有意义的事情。 React.createElement所做的只是生成一个描述要渲染内容的小对象。该对象将大致像这样(我省略了一些东西):
{
type: SomeOtherComponent,
props: null,
key: null,
ref: null,
}
仅创建这些对象就不会导致安装任何组件或经历整个生命周期。相反,它们必须由render函数返回。在您的情况下,更重要的是,Container不是将其作为渲染对象返回,而是作为传递的道具。因此,在Container调用render之后,react将看到它应该挂载一个View。它这样做是从上方将对象作为道具传递。然后,此新安装的视图将呈现,并作为其一部分最终返回对象。只有在这时,React才会安装该组件。
因此,如果“实例化”表示“已安装”,则它将首先开始安装Container,然后是View,然后是SomeOtherComponent。 SomeOtherComponent首先完成安装,然后完成View,然后完成Container。
答案 1 :(得分:1)
constructor
和render
方法以正确的顺序运行。 componentDidMount
按照您的描述运行。
答案 2 :(得分:0)
当您显示相应的视图时,它将被实例化。发生这种情况是因为组件会对DOM中的呈现做出反应,而不仅仅是导入它。 在下一个示例中,如果从App的呈现方法中删除“ {component}”,则NotUsedComponent不会被初始化,并且componentDidMount内部的console.log不会被调用。
import React from "react";
import ReactDOM from "react-dom";
import "./styles.css";
class NotUsedComponent extends React.Component {
componentDidMount() {
console.log("NotUsedComponent is mounted");
}
render() {
return <div />;
}
}
function App() {
const component = <NotUsedComponent />;
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
{component}
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
所以没有渲染-没有初始化。