2017-12-25 19 views
0

次のコンポーネントを使用して、ヒーローとセルの両方を作成するファクトリを呼び出し、配列がいっぱいになると、同じ名前の状態変数に渡します。Redux状態は更新されましたが、依然として未定義として受信された

Field.js

import React,{Component} from 'react'; 
import { connect } from 'react-redux'; 

import _ from "lodash"; 

import Factory from './../Factory/Factory'; 
import { addHero, addCell } from './../../store/actions/actionsCreator'; 

class Field extends Component { 

    componentWillMount(){ 
     let heros = [], 
      cells = []; 

     //id=0 will throw a error, always start with 1 
     for (let i = 1; i < 3; i++) { 
      heros.push(this.callFactory('hero', i)); 
     } 
     this.props.addHero(heros); 

     for (let i = 1; i < 4; i++) { 
      for (let j = 1; j < 12; j++) { 
       let cell = this.callFactory('cell', j, i); 
       cells.push(cell); 
      } 
     } 
     this.props.addCell(cells); 

     this.movePerson(1, {x: 2, y: 1}); 
    } 


    callFactory(type, id, number){ 
     return Factory.build(type, id, number) 
    } 


    render() { 
     const {heros,cells} = this.props; 

     if(heros === undefined) return null; 

     // console.log(this.props); 

     return (
      <div> 
       <table> 
        <tbody> 
         <tr> 
          {cells[0]} 
         </tr> 
        </tbody> 
       </table> 
       {heros[0]} 
      </div> 
     ); 
    } 
} 

const mapStateToProps = state => { 
    return { 
     heros: state.heros, 
     cells: state.cells 
    } 
} 

const mapDispatchToProps = dispatch => { 
    return { 
     addHero(hero) { 
      dispatch(addHero(hero)); 
     }, 
     addCell(cell) { 
      dispatch(addCell(cell)); 
     } 
    } 
} 

export default connect(mapStateToProps, mapDispatchToProps)(Field); 

私の減速ファイルがあります:

index.js(減速ファイル)

import {createStore } from 'redux' 

const initialState = { 
    heros: [], 
    cells: [] 
}; 

const reducer = (state, action) => { 

    switch (action.type) { 
     case 'ADD_HERO': 
      return { 
       ...state, 
       heros: [...state.heros, action.hero] 
      } 

     case 'ADD_CELL': 
      return { 
       ...state, 
       cells: [...state.cells, action.cell] 
      } 

     default: 
      return { 
       ...state 
      } 
    } 

} 

export default createStore(reducer, initialState); 

ファイルには、すべての私の行動で:

actionCreator.js

const addHero = hero => { 
    return { 
     type: 'ADD_HERO', 
     hero 
    } 
} 

const addCell = cell => { 
    return { 
     type: 'ADD_CELL', 
     cell 
    } 
} 


export { addHero, addCell }; 

そして、私のアプリのエントリポイント:私は、任意の時点で私の小道具値を記録しようとすると、

index.js

import registerServiceWorker from './registerServiceWorker'; 

import React from 'react'; 
import ReactDOM from 'react-dom'; 
import { Provider } from 'react-redux'; 

import './styles/index.css'; 

import Field from './components/Field/Field'; 
import store from './store/index'; 

ReactDOM.render(
    <Provider store= {store}> 
     <Field/> 
    </Provider>, 
    document.getElementById('root') 
); 
registerServiceWorker(); 

ここで重要な問題ですそれは未定義として記録されますが、私が内部でpropsを記録すると、それは2回呼び出されます。最初のものは未定義で、2番目は更新された状態です。 この問題を処理する方法はないので、レンダリングの外側で小道具の値を使用できますか?

+0

ロジックが健全に見えます。最初にヒーローやセルを持たないコンポーネントをレンダリングした後、そのレンダリングの後にcomponentDidMountを呼び出してヒーローをロードし、状態が更新された後に再びレンダリングされ、ヒーローが定義されます。小道具は、状態が更新されたらレンダリングの外で使用することができます。あなたはそれらをcomponentWillReceivePropsにログすることができます – brub

+0

私はあなたがcomponentWillMountを使用していることに気づきました。そうでない場合は、最初のレンダリング後に実行されるcomponentDidMountでそのタイプのロジックを実行したいと考えています。https://reactjs.org/docs/react-component.html#componentwillmount – brub

+0

こんにちは、私はちょうどあなたが私のロジックを指摘したので、この分野では非常に悪いです。 WillMountの代わりにComponentDidMountの中でこれらのことをする以外に、配列をフィールドに渡すでしょうか?それでwillMountにアクセスすることができます。 – arnausd

答えて

0

この2つの反応成分サイクルを見てください。 最初はcomponentDidMount()です。あなたはcomponentWillMount()の代わりにこのメソッドを使うべきです。 2番目はcomponentWillReceiveProps(nextProps)です。このメソッドの助けを借りて、あなたはnextPropsの変更を見ることができ、現在あなたが持っている小道具を見ることができます。

+0

こんにちは@ yasinvは、このように動作するようにすべてのコードを変更しようとすると助けてくれてありがとう! – arnausd

0

@brubと@yasinvが指摘しているように、主な問題はComponentDillMountではなく、ComponentWillMount内のすべてのロジックを呼び出すことでした。 誰かが同じ場所にいる場合は、この情報(herosとcells)をFieldコンポーネントに渡し、このデータを処理するためにComponentDidMountをトリガーすることにしました。

関連する問題