2016-05-05 20 views
0

我正在做什麼。我想不出如何正確地傳遞一個REST響應對象到一個ReactJS子組件

我想設置一個multi select list box,以便用戶可以設置屬於父test suitetest cases的列表。

爲此,我創建了一個component,其中顯示test suite的詳細信息。在那之後,我又創建了另一個component以獲取當前的test cases列表以及他們可以從中選擇的可用列表test cases

處理組件時,我撥打RESTHTTP GET調用以獲取test suite的當前分配的test cases

我在如何設置要使用的較低組件的數據有問題。

定義ListBoxWidget時,我無法正確設置selectedListObjects,因爲在初始渲染時狀態對象爲空。調用以填充組件的RESTcomponentDidMount內正在調用,但反應繼續呈現組件。

      <ListBoxWidget 
           unselectedListObjects={unselectedListObjects} 
           selectedListObjects={this.state.selectedListObjects} /> 

ListBoxWidget當我去設置它最初被設定爲任何狀態,因爲沒有價值呢。

問題

1)如何應設置一個輸入元件的初始值?

2)我應該設置ListBoxWidget以不同方式獲取其初始值的方式嗎?我看不到如何做到這一點,並使onChange正常工作。

我的另一個想法是重寫底層的NPM'react-dual-listbox'類,這樣我就可以嘗試在<select>上使用defaultValue=,但我不知道這是否允許在React中使用。

解決方案:我添加了等待渲染直到selectedListObjects狀態被設置的能力。

{this.props.objectName == "Test Suite" && this.state.selectedListObjects != null && 
      <ListBoxWidget 
       unselectedListObjects={unselectedListObjects} 
       selectedListObjects={this.state.selectedListObjects} /> 

謝謝

下面是代碼:

UpdateDialog.js(注意:我已刪除的這部分地區)

class UpdateDialog extends React.Component { 

    constructor(props) { 
    super(props); 
    this.state = {selectedListObjects: [], unselectedListObjects: []}; 
    this.handleSubmit = this.handleSubmit.bind(this); 
    this.onChange = this.onChange.bind(this); 
    this.setupTestSuite = this.setupTestSuite.bind(this); 
    } 

    onChange(selected) { 
    this.setState({ selected }); 
    } 

    setupTestSuite() { 
    var testCasesHref = this.props.object.entity._links.testCases.href; 
    console.log("this.props.object.entity._links.testCases.href " + testCasesHref) 
    // we need to make a call to get all of the test cases 


    var selectedListObjects = []; 

    client({ 
     method: 'GET', 
     path: testCasesHref 
    })........ // set the selected objects in the state 
     this.setState({ 
     selectedListObjects: selectedListObjects 
     }); 
    }); 
    } 

    componentDidMount() { 
    console.log("calling componentDidMount in update"); 

    if (this.props.objectName == "Test Suite") { 
     this.setupTestSuite(); 
    } 
    } 

    render() { 

    var dialogId = "updateObject-" + this.props.object.entity._links.self.href; 

    var listObjects; 
    var selectedListObjects; 

    var unselectedListObjects = [ 
      { value: "http://localhost:8081/api/testCases/1", label: 'Test Case 1' }, 
      { value: "http://localhost:8081/api/testCases/2", label: 'Test Case 2' }, 
      { value: "http://localhost:8081/api/testCases/3", label: 'Test Case 3' }, 
      { value: "http://localhost:8081/api/testCases/4", label: 'Test Case 4' }, 
     ]; 


      var selectedListObjects = ["http://localhost:8081/api/testCases/1"]; // NOTE if I set this it will take the value 
    console.log("setting up render for update dialog with state " + this.state.selectedListObjects); 

    return (
     <div> 

      <form> 
       {inputs} 
       {this.props.objectName == "Test Suite" && 
       <ListBoxWidget 
        unselectedListObjects={unselectedListObjects} 
        selectedListObjects={this.state.selectedListObjects} /> 
       } 
       <button onClick={this.handleSubmit}>Update</button> 
      </form> 
      </div> 
     </div> 
     </div> 
    ) 
    } 

} 

module.exports = UpdateDialog 

注:我已經包括無功selectedListObjects在渲染中,如果這被用來設置選定列表的值而不是它的工作狀態,但這是因爲它不需要打電話來獲取實際值並在初始渲染內定義。

var selectedListObjects = ["http://localhost:8081/api/testCases/1"]; // NOTE if I set this it will take the value 

ListBoxWidget。JS

'use strict'; 

const React = require('react'); 

// import components 
const DualListBox = require('react-dual-listbox'); 

class ListBoxWidget extends React.Component { 
    constructor(props) { 
     super(props); 
     console.log("**** calling to set state in constructor with " + this.props.selectedListObjects); 
     this.state = { selected: this.props.selectedListObjects }; 
     this.onChange = this.onChange.bind(this); 
    } 

    onChange(selected) { 
     this.setState({ selected }); 
    } 

    componentDidMount() { 
     console.log("---- calling mount "); 
    } 

    render() { 

     console.log("render in list box widget"); 

     console.log("this.state.selected inside widget-"+this.state.selected+"-"); 
     console.log("this.props.selectedListObjects inside widget-"+this.props.selectedListObjects+"-"); 

     return (
      <DualListBox 
      name="Test Cases" 
      options={this.props.unselectedListObjects} 
      preserveSelectOrder 
      selected={this.props.selectedListObjects} 
      onChange={this.onChange} /> 

     ) 
    } 
} 

module.exports = ListBoxWidget 

控制檯輸出:

UpdateDialog.js:108 setting up render for update dialog with state 
ListBoxWidget.js:11 **** calling to set state in constructor with 
ListBoxWidget.js:26 render in list box widget 
ListBoxWidget.js:28 this.state.selected inside widget-- 
ListBoxWidget.js:29 this.props.selectedListObjects inside widget-- 
UpdateDialog.js:108 setting up render for update dialog with state 
ListBoxWidget.js:11 **** calling to set state in constructor with 
ListBoxWidget.js:26 render in list box widget 
ListBoxWidget.js:28 this.state.selected inside widget-- 
ListBoxWidget.js:29 this.props.selectedListObjects inside widget-- 
ListBoxWidget.js:21 ---- calling mount 
UpdateDialog.js:78 calling componentDidMount in update 
UpdateDialog.js:41 this.props.object.entity._links.testCases.href http://localhost:8081/api/testSuites/1/testCases 
ListBoxWidget.js:21 ---- calling mount 
UpdateDialog.js:78 calling componentDidMount in update 
UpdateDialog.js:41 this.props.object.entity._links.testCases.href http://localhost:8081/api/testSuites/2/testCases 
UpdateDialog.js:57 objectMap 
UpdateDialog.js:58 [Promise, Promise] 
UpdateDialog.js:57 objectMap 
UpdateDialog.js:58 [Promise] 
UpdateDialog.js:63 objects 
UpdateDialog.js:64 [Object, Object] 
UpdateDialog.js:65 calling for each 
UpdateDialog.js:67 testCase._links.self.hrefhttp://localhost:8081/api/testCases/1 
UpdateDialog.js:67 testCase._links.self.hrefhttp://localhost:8081/api/testCases/3 
UpdateDialog.js:108 setting up render for update dialog with state http://localhost:8081/api/testCases/1,http://localhost:8081/api/testCases/3 
ListBoxWidget.js:26 render in list box widget 
ListBoxWidget.js:28 this.state.selected inside widget-- 
ListBoxWidget.js:29 this.props.selectedListObjects inside widget-http://localhost:8081/api/testCases/1,http://localhost:8081/api/testCases/3- 
UpdateDialog.js:63 objects 
UpdateDialog.js:64 [Object] 
UpdateDialog.js:65 calling for each 
UpdateDialog.js:67 testCase._links.self.hrefhttp://localhost:8081/api/testCases/1 
UpdateDialog.js:108 setting up render for update dialog with state http://localhost:8081/api/testCases/1 
ListBoxWidget.js:26 render in list box widget 
ListBoxWidget.js:28 this.state.selected inside widget-- 
ListBoxWidget.js:29 this.props.selectedListObjects inside widget-http://localhost:8081/api/testCases/1- 

回答

1

我想你使用狀態和componentDidMount獲取與初始數據填充它正確地做它 - 這裏沒有問題。與子控件的問題,您可以通過兩種方式解決:

  1. 如果有可能改寫控制 - 使它,所以它可以處理selectedListObjects財產的缺乏和渲染本身沒有選擇或選擇的第一個對象 - 不管是更適合你的情況。

  2. 不要在父代render中呈現ListBoxWidget,直到您將獲取componentDidMount中的數據爲止。檢查this.state.selectedListObjects是否未定義 - 跳過呈現ListBoxWidget,或呈現而不是它的存根與等待圖標顯示用戶數據正在加載。

希望這會有所幫助。

+0

我剛剛給了2號一槍,它的工作完美。出於某種原因,我沒有想到。另外你如何設置等待圖標直到其渲染的能力?是否有一個特定的npm庫用於它?謝謝 – ALM

+0

不客氣。最簡單的方法是在中心渲染同樣大小的灰色div與中心動畫圖標(好的等待圖標的例子:https://fortawesome.github.io/Font-Awesome/examples/)。 – Amid

相關問題