2015-06-18 26 views
4

我在探索ReactJS並試圖掌握核心概念。我開始拼湊一個原型,我對工作的應用程序有具有深層次數據的ReactJS數據流

  • 客戶
    • 位置以下層次
      • 地址
      • 聯繫

我正在處理的頁面將成爲客戶及其所有相關子項的輸入表單。這些部分中的每一部分都會有一些文本輸入來存放數據,因此它們似乎是容納組件層次結構的自然場所。

從我讀過的關於ReactJS的一切中,如果你要管理狀態,你應該在所有控件的共同祖先中這樣做。這意味着孩子的任何變化都應該讓事件發生在國家的守護者處理變化。這應該更新狀態,並且任何更改都將被重新渲染。這在簡單的情況下是有道理的,但是這使我略微更復雜一些。

  • 如果在許多地址之一發生變化,我是否應該將該事件冒泡到位置然後發送給客戶?
  • 如果是這樣,告訴狀態哪個特定地址改變的最好方法是什麼?
  • 如果您不得不通過層次結構的每個級別進行調用,那麼這是否會使大量額外的樣板文件傳播一個簡單的更改?
  • 我應該在每個文本框上附加onChange事件,還是應該等到我提交表單才能收集數據?

陣營大約ReactLink(https://facebook.github.io/react/docs/two-way-binding-helpers.html)談判的方式來管理更復雜的數據綁定,但並沒有給出如何與一個更大的層級管理它一個很好的例子。另外,它指出大多數應用程序不應該需要這個。那麼,這個應用程序確實不復雜,只是一對具有共享狀態的嵌套控件。這就是React應該發光的地方,所以我不會立即跳到邊緣案例解決方案。

+0

,我認爲你缺少的部分是如何操作的狀態。在您的示例中,數據將在Customer中進行管理,然後通過道具傳遞給您的其他組件。同樣,你可以創建你的函數來處理在Customer中改變狀態的事件,然後通過道具作爲回調傳遞給它們。然後,子組件可以使用回調在發生事件時更改狀態。 – Mark

+0

@Mark我也是這麼理解的,但只要你深入一層,就會通過幾層組件發送回調。所以Location必須傳遞一個與其行爲無關的回調。這是React希望你如何處理它的嗎?如果這樣的話很好,那麼對於React的其他方面如何優雅感覺就有點笨拙。 –

+1

是的,你必須通過幾層組件傳遞迴調。由於您使用的是JSX,因此處理此問題的一個優雅方式是使用JSX spread屬性(https://facebook.github.io/react/docs/transferring-props.html),該屬性允許您傳遞使用的所有道具'{...} this.props'。這在通過多層組件傳遞許多道具時非常有用。 – Mark

回答

1

我最近面臨同樣的謎題 - React文檔在這方面並不完整。這是一個方式,我發現工作:

var Parent = React.createClass({ 
    mixins: [React.addons.LinkedStateMixin], 

    getInitialState: function() { 
     return { 
      p: 'Hello World', 
      q: 'Click me if I\'m pink!', 
      r: 'A' 
     }; 
    }, 
    render: function() { 
     return (
      <div className='parent'> 
       <p> 
        <h3>Parent</h3> 
        <tt> 
         p: {this.state.p}<br /> 
         q: {this.state.q}<br /> 
         r: {this.state.r} 
        </tt> 
       </p> 

       <Child q = {this.linkState('q')} 
         p = {this.linkState('p')} 
         r = {this.linkState('r')} /> 
      </div> 
     ); 
    } 
}); 
var Child = React.createClass({ 
    clicked: function() { 
     this.props.q.requestChange("Thank you :)"); 
    }, 
    render: function() { 
     return (
      <div className='child'> 
       <h3>Child</h3> 

       <p> 
        <input valueLink={this.props.p} /> 
       </p> 

       <p> 
        <tt onClick={this.clicked}> 
         {this.props.q.value} 
        </tt> 
       </p> 

       <select valueLink={this.props.r}> 
        <option value={'A'}>A</option> 
        <option value={'B'}>B</option> 
       </select> 
      </div> 
     ); 
    } 
}); 

React.render(<Parent />, document.body) 

https://jsfiddle.net/cachvico/p81s75x5/

如果任何人有任何改進,我會很高興聽到他們的聲音!

+0

jsfiddle提供了一些錯誤:未捕獲的類型錯誤:undefined不是函數 jsfiddle-integration.js:8未捕獲的類型錯誤:undefined不是函數 – jcalfee314

+0

仍然適用於我的常規Chrome 43.0.2357.130和Firefox 38.0.5 – cachvico

0

我很多時候遇到了這個問題,儘量少做組件的副作用。

因爲在實際狀態處於最高級別(容器),所以我必須將等級下移到4-5級別。

下面是一個例子:

<ProjectContainer> 
 
    <ProjectComponent onProjectChange onProjectTaskChange onCommentChange> 
 
    <ProjectTasksComponent onProjectTaskChange onCommentChange> 
 
     <ProjectTaskComponent onProjectTaskChange onCommentChange> 
 
     <ProjectTaskCommentsComponent onCommentChange> 
 
      <ProjectTaskCommentComponent onCommentChange>

+0

As我已經學會了,因爲我已經習慣了React和Angular 2的組件結構,這是處理事情的默認方式。如果您想要避免這種類型的模式,您可以查看像Flux這樣的模式或者像Redux這樣的庫來集中完成單向數據流的狀態更改。 –