React JSX:父组件的重新渲染是否会重新加载子组件?

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版) 我这样做是通过提供可创建主页,一个函数可能会在每个渲染中重新创建主页。

所以问题就变成了,如何在道路上的每个渲染中不通过页面的娱乐而传递道具?

+1

你可以添加你的ChildComponent代码吗?它不应该多次调用componentDidMount,除非你导航。 – Dev

+0

可能的罪魁祸首是孩子正在接收一组更新的道具或状态,它们会引发重新渲染。请分享您的儿童组件。 –

+0

查看更新:()=>里面的路线是我想的问题引起的。 子组件代码被替换为一个虚拟实体,该虚拟实体除了将生命周期方法记录到控制台以外,无法进行调试。所以问题出现在父组件中,我相信它在我的问题的更新部分。 –

我确认这个问题与我最近的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,但不是父

我希望我能正确理解你的问题!

+0

查看更新:()=>里面的路线是我想的问题。 –

+0

@Feyzi回答更新 – Alex