2017-06-08 7 views
3

状態を更新することを目的とした機能は完全には機能しません。React状態の更新をすぐに行うにはどうしたらいいですか?

私が変更した現在の状態のディープコピーを作成し、その状態に変更したコピーを設定します。私はコピー上で単純なマップを実行し、配列内の各オブジェクトのプロパティを更新することにしました。これにより、アプリケーションの更新状態が直ちに変更されました。 (下のコードには表示されていませんが、私が試したもの)

しかし、私は真にコピーを作りたいと思っています。 setStateは非同期になるので、変更がすぐには起こらないことを理解していますが、どうすればこの問題を解決できますか?なぜなら、関数が2回目にトリガされたときに変更が表示されるからですが、最初の実行時にその関数を実行する必要があります。あなたが望むなら、あなたが構築しているもののライブデモをhttps://non.mpedersen.me/に見ることができます。 App.js

addressSearch(address){ 
    console.log('firing search for distance. Origin is: ' + address) 
    let origin = [address]; 
    const newStores = JSON.parse(JSON.stringify(this.state.stores)) 
    let service = new google.maps.DistanceMatrixService(); 

    newStores.map(store => service.getDistanceMatrix({ 
     origins: origin, 
     destinations: store.addressapi, 
     travelMode: 'DRIVING', 
    }, result => { 
     store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, ''); 
     store.duration = result.rows["0"].elements["0"].duration.text; 
    })) 

    newStores.sort((a,b) => a.distance - b.distance); 
    this.setState({stores : newStores}) 
    } 
+0

をところで、 '' constのnewStores = JSON.parse(JSON.stringify(this.state.stores))をアップ何?何がポイントなのですか – enapupe

+0

詳細なお返事ありがとうございます、私はあなたの提案をお試しになります。私はスライスで深いコピーを作ろうとしましたが、新しい配列は古いものを参照するようになりました。私は状態を直接変更したくないので、元の状態の独立したコピーを作成したいと思っていました – mpleonardo

+0

それはオブジェクトですか? 'const newStores = {... this.state.stores}' .. これは 'immutable.js'を使う良い理由です:) – enapupe

答えて

0

これは、それを解決:)

getDistanceMatrix = (address, store) => { 
    return new Promise((resolve) => { 
     let service = new google.maps.DistanceMatrixService(); 
     let origin = [address]; 
     service.getDistanceMatrix({ 
     origins: origin, 
     destinations: store.addressapi, 
     travelMode: 'DRIVING', 
     }, result => { 
     store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, ''); 
     store.duration = result.rows["0"].elements["0"].duration.text; 
     resolve(store) 
     }) 
    }) 
    } 

    addressSearch(address){ 
    console.log('firing search for distance. Origin is: ' + address) 
    const newStores = JSON.parse(JSON.stringify(this.state.stores)) 
    Promise.all(newStores.map(store => this.getDistanceMatrix(address, store))).then(newStore => { 
     newStores.sort((a,b) => a.distance - b.distance); 
     this.setState({stores : newStores}) 
    }) 
    } 
4

機能は、あなたはsetStategetDistanceMatrix、すべての後には完了している必要がありますし、あなたのマップが行われます。その関数は非同期で実行されるため、setStateのときに関数の補完は実際には得られません。完了は別のスタックで行われます。

このようなシナリオの処理に役立つため、約束は本当に良いです。 JSメカニズム(イベントループ)の性質を示しているので、これは本当に素晴らしい質問です。

あなたのアイデアを取得する場合、それは適切な場所にあなたを取得しますが、このコードを試してみてくださいしかし、私はそれをrunned /テストしていないことを知っている:

ところで
const getDistanceMatrix = (store) => { 
    return new Promise((resolve) => { 
     service.getDistanceMatrix({ 
     origins: origin, 
     destinations: store.addressapi, 
     travelMode: 'DRIVING', 
     }, result => { 
     store.distance = result.rows["0"].elements["0"].distance.text.replace(/\Dkm/, '').replace(/,/,'.').replace(/\s/, ''); 
     store.duration = result.rows["0"].elements["0"].duration.text; 
     resolve(store) 
     }) 
    }) 
    } 

    addressSearch(address){ 
    console.log('firing search for distance. Origin is: ' + address) 
    let origin = [address]; 
    const newStores = JSON.parse(JSON.stringify(this.state.stores)) 
    let service = new google.maps.DistanceMatrixService(); 

    Promise.all(newStores.map(getDistanceMatrix).then((newStores) => { 
     newStores.sort((a,b) => a.distance - b.distance); 
     this.setState({stores : newStores}) 
    }) 
    } 

を、約束が解決された後、非同期の状態を設定しますホストコンポーネントがもはやマウントされていないと、エラーが発生する可能性があります。これは、実際にはレフィックスのようなパターンを採用する優れた理由です。このようなことを多く簡略化します!

+0

Reduxを実装する予定ですしかし、まず私は国家がどのようにReactで働くのかを理解したい。私はこれを実装しようとするが、エラーが表示されます: "ReferenceError:ストアが定義されていませんそれは店のthatsは、約束をnewStores配列のマップ関数の最初の引数として渡されます。なぜそれを調べるのでしょうか?私はそのエラーを受け取り、それをどのように解決できるかを見ていますか? – mpleonardo

+0

マップには1つの引数があります。関数iterator。エラーの修正を使って答えを編集しました。 – enapupe

+0

起源ではない、新しいストアとサービスはgetDistanceMatrixの中で宣言されるべきですか? – mpleonardo

関連する問題