React JSX:父组件的重新渲染是否会重新加载子组件?
在我的阵营应用程序的根组件,我有这样的:React JSX:父组件的重新渲染是否会重新加载子组件?
class App extends Component {
...
ComponentDidMount() {
window.addEventListener('resize', this.handleResize, false);
}
handleResize{
this.parentSize = {height: window.innerWidht - this.node.offsetLeft ..., width: ...};
this.forceUpdate();
}
render() {
<div ref="e=>this.node=e}>
<ChildComponent parentSize={this.ParentSize} />
</div>
}
}
我注意到,当应用程序组件重新呈现,无论是通过的setState或forceUpdate(),子组件实际上是重新安装(这样componentWillUnmount, componentWillMount,每次更新时调用componentDidMount)。我期望的行为是只再次调用Child组件的渲染函数。我最近升级到React-router 4.x,所以我不确定它是否与此有关。
有人可以告诉我,如果这是由设计?让我的componentDidMount多次调用会导致一些问题,因为我试图在其中获取数据,并且我不想在调整大小时多次执行那些昂贵的操作。
UPDATE:
我发现这个问题的可能原因。我有多个嵌套的组件,并且由于很难发布整个项目,所以有时很难发布导致问题的实际代码。但我认为这是它:
return (
<div className="app-view" style={style} ref={el=>this.node=el}>
<Switch>
<Route exact path='/' component={() => <Home store={store} />} />
<Route path='*' component={Error404} />
</Switch>
</div>
);
在这里,我试图通过道具的组件(路径阵营路由器4.x版) 我这样做是通过提供可创建主页,一个函数可能会在每个渲染中重新创建主页。
所以问题就变成了,如何在道路上的每个渲染中不通过页面的娱乐而传递道具?
我确认这个问题与我最近的React-Router 4.x升级有关。 React-Router的文档:
当您使用组件(而不是render或children,如下)时,路由器使用React.createElement从给定组件创建一个新的React元素。这意味着,如果您为组件属性提供内联函数,则每个渲染都会创建一个新组件。这会导致现有组件卸载和安装新组件,而不是仅更新现有组件。使用内联函数进行内联渲染时,请使用渲染或子项目(如下所示)。
感谢大家的支持。
在我看来,您发布的代码中提到的功能都会更改this.parentSize
,然后重新渲染页面。事件如果this.parentSize
值不会改变,其价值正在被重新分配:
this.parentSize = {height: window.innerWidht - this.node.offsetLeft ..., width: ...};
如果我的理解是正确的,那么它是必要的子组件重新渲染,因为用来生成组件具有信息改变,因此组件必须重新渲染以考虑道具变化。很可能情况是DOM没有改变,所以页面不会在视觉上改变。
您可以通过使用Perf add和使用printOperations
函数来检查正在执行的操作。为了防止再次呈现
一种方法是使用shouldcomponentupdate
并返回false时,你不希望组件重新渲染
编辑:
根据上面提供的信息,看来你想通过调用父组件上的函数来更新子组件,但不希望父级重新渲染?
如果是这样的话,你可以通过执行以下操作做到这一点:
第一次孩子组件呈现,你叫componentWillMount
,并得到你希望能够从父控制道具,并保存为国家,像这样:
componentWillMount() {
const { myProp } = this.props;
this.setState({
myProp
});
}
然后在此组件你犯了一个函数调用是这样的:
updateMyProp(newProp) {
this.setState({
myProp: newProp
})
}
从此,这款v良莠不齐由state
控制,而不是props
接下来,父页上,组件需要有一个ref
变量,就像这样:
<Yourcomponent
ref={d=> this.componentName = d}
...
/>
现在,从父页面,您可以拨打updateMyProp
功能通过执行以下操作:
this.componentName.updateMyProp(someNewValue)
这会让孩子组件renreder,但不是父
我希望我能正确理解你的问题!
查看更新:()=>
@Feyzi回答更新 – Alex
你可以添加你的ChildComponent代码吗?它不应该多次调用componentDidMount,除非你导航。 – Dev
可能的罪魁祸首是孩子正在接收一组更新的道具或状态,它们会引发重新渲染。请分享您的儿童组件。 –
查看更新:()=>里面的路线是我想的问题引起的。 子组件代码被替换为一个虚拟实体,该虚拟实体除了将生命周期方法记录到控制台以外,无法进行调试。所以问题出现在父组件中,我相信它在我的问题的更新部分。 –