2016-05-05 1 views
0

何をしようとしていますか?ReactJS子コンポーネントにRESTレスポンスオブジェクトを正しく渡す方法がわかりません

multi select list boxを設定して、test casesのリストをユーザがtest suiteに属するように設定したいと考えています。

これを行うにはtest suiteの詳細を示すcomponentを作成しました。その中で私はtest casesと利用可能なリストtest casesの現在のリストを取る別のcomponentを作成しました。

私はRESTHTTP GET呼び出しがtest suiteの現在test casesを割り当てられて取得する構成するコンポーネントを処理します。

下位コンポーネントが使用するデータを設定する方法に問題があります。

ListBoxWidgetを定義すると、初期レンダリング時に状態オブジェクトが空であるため、selectedListObjectsを正しく設定できません。 RESTがコンポーネントを生成するために呼び出されると、componentDidMountが呼び出されていますが、反応してコンポーネントがレンダリングされ続けます。 ListBoxWidget

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

私が最初に状態を設定するために行くときは値がまだ存在しないので、それが何に設定されています。

質問

1)どのように私は、入力要素の初期値を設定すべきですか?

2)ListBoxWidgetの状態が初期値とは異なる状態を設定する必要がありますか?私はこれを行う方法を知ることができず、onChangeを正しく動作させることができませんでした。

私の他の考えは、<select>defaultValue=を使用しようとすることができるように、基盤となるNPMのreact-dual-listboxクラスを書き直すことですが、それが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 

注:私はVARが含まれている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を使用して、正しくそれを作ったと思います。それはselectedListObjects財産の不在を処理し、選択することなく、または選択された第1のオブジェクトに自身をレンダリングすることができるようにそれを作る - - であるものは何でもあなたがコントロールを書き換える可能性がある場合は

  1. :あなたの2つの方法で解決することができる子コントロールの問題あなたの場合より適切です。

  2. componentDidMountにデータを取得するまで、ListBoxWidgetを親のrenderに表示しないでください。 this.state.selectedListObjectsが未定義であるかどうかをチェックする - ListBoxWidgetのレンダリングをスキップするか、待機中のスタブの代わりにスタブをレンダリングして、データがロードされていることをユーザーに示します。

希望します。

+0

私はちょうど2番打撃を与え、それは完全に働いた。私は何らかの理由でそれを考えなかった。また、レンダリングされるまで待機アイコンを持つ能力をどのように設定しますか?それに使用する特定のnpmライブラリがありますか?ありがとうございます – ALM

+0

ようこそ。最も簡単な方法は、同じ大きさの灰色のdivを中央のアニメーションアイコンの内側にレンダリングすることです(いい待機アイコンの例:https://fortawesome.github.io/Font-Awesome/examples/)。 – Amid

関連する問題