2016-07-28 9 views
2

Redux 저장소에 연결된 React 구성 요소가 있습니다. 나는 수명주기 방법 인 componentWillMount에서 자원 (게시물)을 가져오고 있습니다.Redux를 사용한 비동기 동작

componentWillMount() { 
    this.props.fetchPosts(); 
} 

구성 요소가 돌아 오는 저장소와 저장소에서 isFetchingposts을 얻기에 가입됩니다.

const mapStateToProps = (state) => { 
    return { 
    posts: getAllPosts(state), 
    isFetching: getIsFetchingPosts(state), 
    } 
} 

내가이 일을하고자하는 render 방법, 그래서 여전히 가져 오는 것 스피너를 보여주고 싶습니다.

render() { 
    if (this.props.isFetching) { 
    return <Spinner /> 
    } 

    return this.props.posts.map(post => <PostItem key={post.id}{...post}/>) 
} 

BUT I는 render 방법을 isFetching CONSOLE.LOG 경우 제 그러므로 false하고 true 최종적 false 나타낸다.

이 컨테이너가 처음 렌더링 될 때 isFetching 상태가 이미 true으로 설정되어 있으며 회 전자를 표시하는 것이 이상적입니다. 그런 일이 일어나기 위해 나는 어떤 변화가 필요합니까? 여기

사전에 감사 조치 작성자에 대한 코드 및 감속기

/*** Action Creator ***/ 
export const fetchPosts =() => (dispatch) => { 
    dispatch({ 
    type: REQUEST_POSTS, 
    }); 

    return axios({ 
    method: 'get', 
    url: `${API_URL}/posts`, 
    }) 
    .then(({data}) => { 
    dispatch({ 
     type: RECEIVE_POSTS, 
     payload: data.posts, 
    }) 
    }) 
    .catch((response) => { 
    // some error handling. 
    }); 
} 


/*** Reducers ***/ 
const initialState = { 
    isFetching: false, 
    allIds: [], 
    byId: {}, 
}; 

const isFetching = (state = initialState.isFetcthing, action) => { 
    switch (action.type) { 
    case REQUEST_POSTS: 
     return true; 
    case RECEIVE_POSTS: 
     return false; 
    default: 
     return state; 
    } 
} 

const allIds = (state = initialState.allIds, action) => { 
    switch (action.type) { 
    case RECEIVE_POSTS: 
     return action.payload.map(post => post.id); 
    default: 
     return state; 
    } 
} 

const byId = (state = initialState.byId, action) => { 
    switch (action.type) { 
    case RECEIVE_POSTS: 
     return action.payload.reduce((nextState, post) => { 
     nextState[post.id] = post; 
     return nextState; 
     }, {...state}); 
    default: 
     return state; 
    } 
} 

const posts = combineReducers({ 
    isFetching, 
    allIds, 
    byId, 
}); 

export default posts; 


/*** Selectors in 'posts.js' file ***/ 

export const getAllPosts = (state) => { 
    const { allId, byId } = state; 
    return allIds.map(id => byId[id]); 
} 

/*** rootReducer file ***/ 
import posts, * as fromPosts from './posts'; 


const rootReducer = combineReducers({ 
    posts, 
}) 

export default rootReducer; 

export const getAllPosts = (state) => { 
    return fromPosts.getAllPosts(state.posts); 
}; 

입니다!

+0

정말 명확하지 않다, 그래서 가상 DOM은 최적화 diffing의 반응 , 당신은 mapStateToProps에 그것을 제공하지 않는다. 그리고 state와 fetchPosts의 게시물 사이의 연결은 무엇입니까 (함수 업데이트 상태입니까?). 이 점을 분명히 해 주시겠습니까? – berliner

+0

처음에'isFetching = false'를 갖는 것은 ok 동작입니다. 즉, 액션이 감속기에 충돌하지 않았 음을 의미합니다. 즉,'fetchPosts'가 플래그를 true로 설정하기 전에'render'가 호출되었습니다. – Igorsvee

답변

1

일반적인 대답은 구현시 예상되는 동작입니다. isFetching 상태를 소품으로 매핑합니다. 여기에 무슨 일이 일어나고 있는지 : 그것은 false로 렌더링 있도록 isFetching 소품 값이 false 그래서 상태 트리에서 isFetching의 초기 값은, false입니다

  1. .

  2. isFetching을 으로 변경하는 작업을 상태 트리에 디스패치합니다. 이 새로운 상태는 새로운 isFetching 보조 값 true에 매핑되며, 이는 다시 렌더링을 유발하여 true으로 렌더링됩니다.

  3. 상태 트리에서 isFetching을 다시 false으로 변경하는 다른 작업을 (비동기 적으로) 발송합니다. (2)와 동일하게 재 렌더링이 발생하며 isFetchingfalse입니다.

평원 솔루션은 단순히이 true, false의 렌더링하려는 경우는 * 현재 구현하여 감속기의 초기 상태에 trueisFetching을 설정하는 것입니다. 이 구현은이 구성 요소는 광범위한 질문 * 완전성에 대한 업데이 트 내가 돈 '이라고해야

:-) 여기에 대답하기에 충분한 상황이 아니라고이다의 디자인 수준에서 의미가 있는지 여부

render() 함수가 두 번 호출되는 경우, isFetchingtrue,false으로 해결되었거나이 경우에 true,true,false으로 세 번 확인되었습니다.맵핑 된 isFetching 소품이 true ->true ->true에서 바뀌면 react-redux가 렌더링 렌더링을 최적화 할 수 있다고 생각합니다. 그러나이를 잘 모르는 경우 - 보내 주시면 고맙고 관심이 있습니다. 당신의 로깅 결과가 무엇인지 압니까? 확실히 두 인해 표준에 발생할 수있는 렌더링하는 DOM 레벨에서 어떤 경우

, 무슨 fetchPosts은 사실상 결과는 같은 어느 쪽이든

+0

답변 해 주셔서 감사합니다! 방금 질문을 업데이트했습니다. "이 컨테이너가 처음 렌더링 될 때 이상적으로 가져 오기 상태가 이미 true로 설정되어 있고 회 전자가 표시됩니다. 변경하려면 어떻게해야합니까?" 이 아이디어가 있습니까? 나는'react-router'를 사용하고 있습니다. –

+0

문제 없습니다. 솔직히 말해서, 이것은 내 자신의 감속기 디자인에서 나 자신과 고민했던 것, 즉 초기 상태를 유지하고 각 구성 요소의 새로운 렌더링마다 초기 상태를 재설정하는 방법입니다. 'isFetching'이 true가되도록 초기 상태를 설정하는 방법으로 가서이 구성 요소를 후속 렌더링하기 전에 상태 트리에서이 객체가 'true'로 재설정되었는지 확인하십시오. 이는 디자인에 따라 다소 힘들 수 있습니다. 또 다른 간단한 방법은'isFetching'을 컴포넌트의 내부 상태로 유지하고 컴포넌트가 getInitialState()를 사용하여 마운트 할 때마다 리셋하는 것입니다. – davnicwil

+0

(cont) 이것은 명확한 대답이없는 디자인 선택 중 하나라고 생각합니다. 앱에 따라 달라집니다 :-) 필자가 말했듯이,이 small-ish 자체 포함 UI 상태를 유지하는 곳은 앱을 redux로 작성할 때 가장 중요한 질문 중 하나입니다. – davnicwil