2016-09-19 8 views
0

내 reactx (4.4.5) 프로젝트에서 react-router-redux (4.0.5)와 redux-async-connect (0.1.13)를 사용합니다. 컨테이너 구성 요소를로드하기 전에 API에서 비동기 적으로 데이터를로드하려고합니다. url은 메시지를 가져 오는 데 사용되는 "category"라는 쿼리 매개 변수를 포함합니다. 즉. 사용자/cornel/messages? category = react-redux비동기 호출에서 쿼리 매개 변수에 액세스

내 위치/경로에 연결된 매개 변수는 state.routing.locationBeforeTransitions에 있지만 비동기 호출에서 최신이 아닙니다. 비동기 함수에 전달되는 params 매개 변수에서 경로 매개 변수를 가져올 수 있지만 쿼리 매개 변수는 포함되어 있지 않습니다.

@statics({ 
    reduxAsyncConnect(params, store) { 
    const { dispatch } = store; 
    return Promise.all([ 
     dispatch(loadMessages(category)) <-- need the query parameter "category" here 
    ]); 
    } 
}) 
@connect(state => ({ 
    messages: state.user.messages 
})) 
export default class HomeContainer extends Component { 
    static propTypes = { 
    dispatch: PropTypes.func 
    messages: PropTypes.array.isRequired 
    }; 

    render() { 
    const { messages } = this.props; 

    return (
     ... 
    } 
    } 
} 

누구나 내가 어떻게 쿼리 매개 변수에 액세스해야 클라이언트와 서버 측 모두에서 작동하는지 알 수 있습니까? 미리 감사드립니다.

답변

1

react-redux-router를 사용하는 경우 redux 상태에서 다음과 같이 검색 할 수 있어야합니다.

@statics({ 
    reduxAsyncConnect(params, store) { 
    const { dispatch } = store; 
    return Promise.all([ 
     dispatch(loadMessages(category)) <-- need the query parameter "category" here 
    /* you might get 
     store.getState(). 
      routing.locationBeforeTransitions.search 
     from here too */ 
    ]); 
    } 
}) 
@connect(state => ({ 
    messages: state.user.messages, 
    /* get search from redux state */ 
    search : state.routing.locationBeforeTransitions.search 
})) 
export default class HomeContainer extends Component { 
    static propTypes = { 
    dispatch: PropTypes.func 
    messages: PropTypes.array.isRequired 
    }; 

    render() { 
    const { messages } = this.props; 

    return (
     ... 
    } 
    } 
} 

내가 사용할 수없는 경우 알려주십시오.

편집 여기

는 reduxAsyncConnect하고 당신이 원하는 것을 달성을 사용하지 않는 코드의 조각이다.

// CONSTANTS 
const 
    GET_SOMETHING_FROM_SERVER = 'GET_SOMETHING_FROM_SERVER', 
    GET_SOMETHING_FROM_SERVER_SUCCESS = 'GET_SOMETHING_FROM_SERVER_SUCCESS', 
    GET_SOMETHING_FROM_SERVER_FAIL = 'GET_SOMETHING_FROM_SERVER_FAIL'; 

// REDUCER 
const initialState = { 
    something : [], 
    loadingGetSomething: false, 
    loadedGetSomething:false, 
    loadGetSomethingError:false 
}; 

export default function reducer(state = initialState, action) { 

    switch(action.type) { 

    case GET_SOMETHING_FROM_SERVER: 
     return Object.assign({}, state, { 
     loadingGetSomething: true, 
     loadedGetSomething:false, 
     loadGetSomethingError:false 
     something : [] // optional if you want to get rid of old data 
     }); 
    case GET_SOMETHING_FROM_SERVER_SUCCESS: 
     return Object.assign({}, state, { 
     loadingGetSomething: false, 
     loadedGetSomething:true, 
     something : action.data 
     }); 
    case GET_SOMETHING_FROM_SERVER_FAIL: 
     return Object.assign({}, state, { 
     loadingGetSomething: false, 
     loadGetSomethingError: action.data 
     }); 
    default: 
     return state; 
    } 

}; 

// ACTIONS 

/* ----------------- GET SOMETHING ACTIONS START ----------------- */ 
import Fetcher from 'isomorphic-fetch'; // superagent , axios libs are okay also 

export function getSomething() { 
    return { 
    type : GET_SOMETHING_FROM_SERVER 
    } 
}; 
export function getSomethingSuccess(data) { 
    return { 
    type : GET_SOMETHING_FROM_SERVER_SUCCESS, 
    data 
    } 
}; 
export function getSomethingFail(data) { 
    return { 
    type : GET_SOMETHING_FROM_SERVER_FAIL, 
    data 
    } 
}; 
export function getSomethingAsync(paramsToBeSentFromComponents){ 
    return function(dispatch) { 
    const fetcher = new Fetcher(); 

    dispatch(getSomething()); // so we can show a loading gif 

    fetcher 
     .fetch('/api/views', { 
     method : 'POST', 
     data : { 
      // use paramsToBeSentFromClient 
     } 
     }) 
     .then((response) => { 
     dispatch(getSomethingSuccess(response.data)); 
     }) 
     .catch((error) => { 
     return dispatch(getSomethingFail({ 
      error : error   
     })) 
     }); 
    } 
} 
/* ----------------- GET SOMETHING ACTIONS END ----------------- */ 


// COMPONENT 

import React, {Component}  from 'react'; 
import { connect }    from 'react-redux'; 
import { bindActionCreators } from 'redux'; 
import * as somethignActions from './redux/something'; 

@connect((state) => ({ 
    pathname : state.routing.locationBeforeTransitions.pathname, 
    something : state.something 
})) 

export default class SettingsMain extends Component{ 

    constructor(props){ 
    super(props); 
    this.somethingActions = bindActionCreators(somethingActions, this.props.dispatch); 
    } 

    componentDidMount(){ 
    // you are free to call your async function whenever 
    this.settingActions.getSomething({ this.props.pathname...... }) 
    } 

    render(){ 
    return (/* your components */) 
    } 
} 
+0

store.getState(). routing.locationBeforeTransitions.search는 빈 문자열입니다. 나는 그것이 최신 URL 변경으로 업데이트되지 않았기 때문에 그것을 생각한다. 구성 요소를 렌더링하는 동안 실제 소품에서 사용할 수 있습니다. –

+0

언제이 기능을 사용해야합니까? 귀하의 구성 요소가 다른 경로의 페이지에 또는 그 전에 마운트 되었습니까? 나는 또한 reduxAsyncConnect에 익숙하지 않다. 당신은 컴포넌트에서 비동기 함수를 쉽게 호출 할 수 있고, 얻은 소품을 전달할 수 있습니다 .... componentWillMount 또는 뭔가 검색. – FurkanO

+0

reduxAsyncConnect는 구성 요소가 마운트되기 전에 함수를 시작합니다. 그것은 react-router-redux v3에서 사용되었습니다. –