2017-12-25 1 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를 기록한다면, 그것은 두 번 호출 될 것입니다. 첫 번째 것은 undefined로, 두 번째 것은 업데이트 된 상태로 호출됩니다. 외부에서 소품 값을 사용할 수 있도록이 문제를 해결할 방법이 있습니까?

+0

논리가 소리가납니다. 먼저 hero 또는 셀이없는 구성 요소를 렌더링하고, 렌더링 한 후에 componentDidMount를 호출하고 heros를로드 한 다음 상태가 업데이트 된 후에 다시 렌더링하고 heros가 정의됩니다. 소품은 상태가 업데이트되면 외부에서 사용할 수 있습니다. 당신은 componentWillReceiveProps에 로그 할 수 있습니다. – brub

+0

방금 ​​componentWillMount를 사용하고있는 것으로 나타났습니다. 렌더링 전에 상태 변경이 실행될 것으로 생각됩니다. 그런 경우가 아닙니다. 초기 렌더링 후에 실행되는 componentDidMount에서 해당 유형의 로직을 수행하려고합니다. https://reactjs.org/docs/react-component.html#componentwillmount – brub

+0

안녕하세요, 감사합니다. 감사합니다. 당신이 잘 내 논리를 지적이 반응/redux로 시작하는 메신저는이 분야에서 매우 나쁘다. 이외에도 WillMount 대신 ComponentDidMount 내부에서이 모든 작업을 수행하면 배열을 필드에 전달할 수 있습니까? 그러면 willMount에 액세스 할 수 있습니다. – arnausd

답변

0

이 두 반응 구성 요소주기를 살펴보십시오. 첫 번째 구성 요소는 componentDidMount()입니다. 이 메소드는 componentWillMount() 대신에 사용해야합니다. 두 번째 구성 요소는 componentWillReceiveProps (nextProps)입니다. 이 방법을 사용하면 nextProps 변경 사항을 볼 수 있으며 현재 보유하고있는 소품을 볼 수 있습니다.

+0

안녕하세요 @ yasinv 도움을 주셔서 감사합니다,이 방법으로 작동하도록 모든 코드를 변경하려고합니다! – arnausd

0

@brub 및 @yasinv가 지적했듯이 주된 문제는 ComponentDillMount가 아니라 ComponentWillMount 내의 모든 로직을 호출하는 것이 었습니다. 누군가가 같은 지점에 있으면이 정보 (heros 및 셀)를 내 Field 구성 요소에 소품으로 전달한 다음 ComponentDidMount를 트리거하여이 데이터를 처리하기로 결정했습니다.

관련 문제