2016-09-19 50 views
0

我的反應redux(4.4.5)項目使用react-router-redux(4.0.5)和redux-async-connect(0.1.13)。在我加載我的容器組件之前,我想從我的API異步加載數據。該url包含一個名爲「category」的查詢參數,用於獲取消息。即。 user/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一起工作。 –