2017-08-11 241 views
0

在我的陣營應用程序的根組件,我有這樣的: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

查看更新:()=>裏面的路線是我想的問題引起的。 子組件代碼被替換爲一個虛擬實體,該虛擬實體除了將生命週期方法記錄到控制檯以外,無法進行調試。所以問題出現在父組件中,我相信它在我的問題的更新部分。 –

回答

2

我確認這個問題與我最近的React-Router 4.x升級有關。 React-Router的文檔:

當您使用組件(而不是render或children,如下)時,路由器使用React.createElement從給定組件創建一個新的React元素。這意味着,如果您爲組件屬性提供內聯函數,則每個渲染都會創建一個新組件。這會導致現有組件卸載和安裝新組件,而不是僅更新現有組件。使用內聯函數進行內聯渲染時,請使用渲染或子項目(如下所示)。

感謝大家的支持。

0

在我看來,您發佈的代碼中提到的功能都會更改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

相關問題