2017-12-05 1 views
1

Redux 썽크 및 액시오를 사용하여 서버 호출을하고 결과에 따라 상태를 수정합니다.서버에서 Redux 상태가 아직 채워지지 않았기 때문에 연결된 구성 요소의 초기 렌더링이 실패합니다.

문제는 내가 연결된 구성 요소를 사용하여 초기 상태는 서버에서 데이터에 의존 할 때, 그것은

render() (<div>{this.props.someData}</data>) // empty, or error, if nested 

... 

const mapStateToProps = state => ({ 
    someData: state.someData 
}) 

가 나는 또한이 시도 (연결 소품이 비어) 렌더링하지 않는다는 것입니다 :

componentWillMount =() => { 
    this.setState({ 
    someData: this.props.someData 
    }) 
} 

staterender에 사용했지만 도움이되지 않았습니다.

렌더링이나 다른 솔루션을 사용하기 전에 서버 응답을 기다리는 방법이 있습니까?

+0

하면 데이터에 대한 요청을하고있다? – Geraint

+0

안녕하세요, 코드에 실수가 있습니다. 전체 구성 요소를 추가 할 수 있습니까? – Dkouk

+0

@Geraint 구성 요소가 라우터 내부에 약간의 레벨로 침투합니다. 일단 경로 매개 변수가 있으면 해당 데이터를 호출합니다. – ilyo

답변

-1

일반적으로 Component.defaultProps 개체를 사용하여 소품을 초기화합니다. 따라서 귀하의 경우에는 axios가 데이터를 받기 전에 someData prop를 초기 값으로 설정합니다.

class MyComponent extends React.Component { 
 
    // ... your implementation 
 
} 
 

 
MyComponent.defaultProps = { 
 
    someData: [] // empty array or whatever the data type is 
 
};

편집 : docs

+1

OP가 빈 구성 요소를 렌더링 한 다음 나중에 업데이트하려고한다고 생각하지 않습니다. 잠시 기다리십시오. 데이터가 여전히 가져 오는 동안로드 구성 요소를 표시 할 수 있으므로 솔루션이 반드시 문제를 해결하지는 않습니다. – brandNew

+0

그는 "... 또는 다른 해결책"이라고 말했습니다. 이것은 일반적으로 데이터가 수신되지 않을 때 렌더링되지 않도록 구성 요소를 중지하는 방법입니다. 구성 요소에'if (! someData) loading else' 로직을 쓰는 것을 막을 수있는 방법은 없습니다. –

+0

좋아, 너 말 들려. 네가 옳아. – brandNew

0

당신은 조건부로 그 부분을 렌더링 할 수 있습니다. 가져 오기 상태를 나타내는 속성을 사용하십시오 (예 : 속성 이름은 loading).

class UserDetails extends React.Component { 
    state = { 
     loading: true, 
     data: null 
    } 

    fetch() { 
     this.setState({ 
      loading: true 
     }) 

     // an axios call in your case 
     setTimeout(() => this.setState({ 
      loading: false, 
      data: { 
       nestedValue: 'nested value' 
      } 
     }), 500) 
    } 

    componentDidMount() { 
     this.fetch() 
    } 

    render() { 
     return <div> 
      {this.state.loading ? <span>loading...</span> : <div>nested prop value: {this.state.data.nestedValue}</div>} 
     </div> 
    } 
} 
0

이 작업을 수행하는 가장 좋은 방법은 액션 제작자와 몇 가지 변수에 Promises을 사용하는 것입니다.

변수는, isLoaded 아마도과 같이 구성 요소에 사용되는 말 :

{ 
    this.props.isLoaded ? <MyComponent /> : <StillLoadingComponent /> 
} 

액션 창조자에서 당신은 다음 Promise 방식으로 API 호출이 데이터를 얻을 수 있도록 것입니다. 이 체크 Promisethen의 일부

데이터가 수신되었는지가

그렇다면, trueisLoaded 속성을 변경한다 IS_LOADED 유형의 작용을 전달. 그래서 같은

state = { 
    isLoaded: false, 
    data: null 
} 

예는 것이 무엇인가 :

당신의 초기 상태 (Initial) 이런 식으로 뭔가를해야만라고 가정

MyComponent.js

... 
render() { 
    if (!this.props.isLoaded) { 
    return (
     <Loader /> 
    ); 
    } 
    else { 
    return (
     <div> 
     <h2>{this.props.actualData}</h2> 
     </div> 
    ); 
    } 
} 
... 

MyComponentContainer.js

... 
const mapStateToProps = state => ({ 
    isLoaded: state.isLoaded 
    actualData: state.data 
}); 
... 

ComponentActions.JS

thunk로 사용되는, 그래서 우리는 지금처럼 쓰기 :

... 
// I am not including getState deliberately 
const loadData = valueToGet => dispatch { 

    //Fetch the data using axios or isomorphic-fetch 
    fetch('some/url' + valueToGet) 
    .then(res => res.json()) 
    .then(actualData => { 
     dispatch({ 
     type: IS_LOADED, 
     payload: actualData 
     }) 
    }) 
} 
... 

ComponentReducer.js

... 
case IS_LOADED: 
    return newState = { 
    ...state, 
    isLoaded: true, 
    data: action.payload 
    } 
... 
관련 문제