<progress id="7nnbd"><big id="7nnbd"><em id="7nnbd"></em></big></progress>

<big id="7nnbd"><meter id="7nnbd"></meter></big>
<progress id="7nnbd"><meter id="7nnbd"><cite id="7nnbd"></cite></meter></progress><meter id="7nnbd"></meter>

      <address id="7nnbd"></address>

          為了賬號安全,請及時綁定郵箱和手機立即綁定

          React router的Route中component和render屬性的使用

          2018.11.23 14:02 2159瀏覽

          在react router官方文檔關于component的部分寫著:

          When you use component (instead of render or children, below) the router uses React.createElement to create a new React element from the given component. That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component. When using an inline function for inline rendering, use the render or the children prop (below).

          這段話如何理解呢?可以通過一個小例子來說明。

          import React from 'react';
          import ReactDOM from 'react-dom';
          import {BrowserRouter, Route} from "react-router-dom";
          
          class Bar extends React.Component {
          
              componentDidMount() {
                  console.log("componentDidMount")
              }
          
              render() {
                  return (
                      <div>Bar</div>
                  )
              }
          }
          
          class App extends React.Component {
          
              constructor(prop) {
                  super(prop);
                  this.state = {idx: 1}
              }
          
              handleClick = () => {
                  this.setState(state => ({idx: state.idx + 1}))
              };
          
              render() {
                  return (
                      <div>
                          <div>
                              {this.state.idx}
                              <button onClick={this.handleClick}>add</button>
                          </div>
                          <div>
                              <BrowserRouter>
                                  <Route component={Bar}/>
                              </BrowserRouter>
                          </div>
                      </div>
                  );
              }
          }
          
          
          ReactDOM.render(<App/>, document.getElementById('root'));
          

          上面的代碼中,App組件內有一個簡單的Bar組件,通過component屬性被Route引用。

          <Route component={Bar}/>
          

          此時在頁面中點擊按鈕,Bar組件的componentDidMount并不會被觸發。
          假設現在需要在Bar組件中接受App中的idx,需要將idx作為props傳遞給Bar,此時可以寫成如下代碼

          import React from 'react';
          import ReactDOM from 'react-dom';
          import {BrowserRouter, Route} from "react-router-dom";
          
          class Bar extends React.Component {
          
              componentDidMount() {
                  console.log("componentDidMount")
              }
          
              render() {
                  const {idx} = this.props;
                  return (
                      <div>in Bar : {idx}</div>
                  )
              }
          }
          
          class App extends React.Component {
          
              constructor(prop) {
                  super(prop);
                  this.state = {idx: 1}
              }
          
              handleClick = () => {
                  this.setState(state => ({idx: state.idx + 1}))
              };
          
              render() {
                  return (
                      <div>
                          <div>
                              {this.state.idx}
                              <button onClick={this.handleClick}>add</button>
                          </div>
                          <div>
                              <BrowserRouter>
                                  <Route component={() => (<Bar idx={this.state.idx}/>)}/>
                              </BrowserRouter>
                          </div>
                      </div>
                  );
              }
          }
          
          
          ReactDOM.render(<App/>, document.getElementById('root'));
          

          然而此時點擊按鈕,發現Bar的componentDidMount一直被調用,就像上面文檔中說的一樣

          That means if you provide an inline function to the component prop, you would create a new component every render. This results in the existing component unmounting and the new component mounting instead of just updating the existing component.

          所以正確的寫法應該是

          <Route render={() => (<Bar idx={this.state.idx}/>)}/>
          

          此時Bar組件就不會出現重復的unmounting和mounting了。

          其背后的原理在于,react在比較組件狀態以便決定如何更新dom節點時,首先要比較組件的type和key。在使用<Route component={() => (<Bar idx={this.state.idx}/>)}/>時,由于調用了React.createElement,組件的type不是Bar這個類,而是一個匿名函數。App組件每次render時都生成一個新的匿名函數,導致生成的組件的type總是不相同,所以會產生重復的unmounting和mounting。

          點擊查看更多內容

          本文首次發布于慕課網 ,轉載請注明出處,謝謝合作

          0人點贊

          若覺得本文不錯,就分享一下吧!

          評論

          相關文章推薦

          正在加載中
          意見反饋 邀請有獎 幫助中心 APP下載
          官方微信

          舉報

          0/150
          提交
          取消
          五福彩票 偃师 | 濮阳 | 扬中 | 雄安新区 | 周口 | 玉环 | 三亚 | 新乡 | 丹东 | 大兴安岭 | 邯郸 | 桐乡 | 茂名 | 南充 | 泉州 | 阿坝 | 张掖 | 咸宁 | 日喀则 | 衢州 | 永州 | 醴陵 | 永康 | 简阳 | 临沂 | 荆门 | 广安 | 海宁 | 河北石家庄 | 吴忠 | 莱州 | 莱州 | 柳州 | 鄂州 | 禹州 | 山南 | 中山 | 宣城 | 雄安新区 | 阿勒泰 | 嘉兴 | 巴音郭楞 | 灌云 | 寿光 | 甘肃兰州 | 滨州 | 甘肃兰州 | 百色 | 临沧 | 江苏苏州 | 六盘水 | 鹰潭 | 上饶 | 如皋 | 仁怀 | 瓦房店 | 广安 | 萍乡 | 乐清 | 天水 | 天门 | 新余 | 曹县 | 中山 | 甘南 | 廊坊 | 宁波 | 陇南 | 仁寿 | 招远 | 焦作 | 唐山 | 泉州 | 张掖 | 琼中 | 丹东 | 雄安新区 | 孝感 | 榆林 | 眉山 | 延安 | 任丘 | 榆林 | 佛山 | 晋江 | 黑河 | 安岳 | 佳木斯 | 任丘 | 韶关 | 如东 | 防城港 | 余姚 | 日喀则 | 平潭 | 嘉善 | 天水 | 廊坊 | 临猗 | 阿拉尔 | 松原 | 邵阳 | 定州 | 柳州 | 林芝 | 台中 | 中山 | 汝州 | 保定 | 张掖 | 荆州 | 海丰 | 玉溪 |