2016-03-07 6 views
19

Я написал компонент контейнера с помощью Redux и моя реализация для mapDispathToProps выглядит следующим образомгосударственный доступ внутрь метода mapDispatchToProps

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
     onChange: (newValue) => { 
      dispatch(updateAttributeSelection('genre', newValue)); 
      dispatch(getTableData(newValue, ownProps.currentYear)); 
     } 
    } 
} 

Проблема в том, что для того, чтобы getTableData мне нужно состояние некоторых других компонентов. Как получить доступ к объекту состояния в этом методе?

ответ

20

Вы можете использовать Redux-преобразователь, чтобы создать отдельный действие функции создателя, который имеет доступ к getState, а не определять функции внутри mapDispatchToProps:

function doTableActions(newValue, currentYear) { 
    return (dispatch, getState) => { 
     dispatch(updateAttributeSelection('genre', newValue)); 
     let state = getState(); 
     // do some logic based on state, and then: 
     dispatch(getTableData(newValue, currentYear)); 
    } 
} 


let mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
     onChange : (newValue) => { 
      dispatch(doTableActions(newValue, ownProps.currentYear)) 
     } 
    } 
} 

Некоторые различные способы, чтобы идти об организации тех, но что-то вроде это должно сработать.

+0

Я думаю, что реальный случай использования для доступа к государству в mapDispatchToProps, чтобы знать, какие действия доступны во время выполнения. Например, вы можете сопоставить все возможные действия с функцией и вызвать ее для отправки действия или протестировать его с помощью предложения if, чтобы проверить, доступно ли действие. –

2

Чтобы получить состояние, вы можете использовать redux-thunk. Написать вспомогательную функцию:

const getState = (dispatch) => new Promise((resolve) => { 
    dispatch((dispatch, getState) => {resolve(getState())}) 
}) 

Вы можете использовать это в асинхронном функции или генератора функции:

const mapDispatchToProps = (dispatch, ownProps) => { 
    return { 
    async someFunction() { 
     const state = await getState(dispatch) 
     ... 
    } 
    } 
} 
0

Возможный подход является также использовать mergeProps, которая сливает mapState и mapDispatch и позволяет использовать оба в то же время.

// Define mapState 
const mapState = (state) => ({ 
    needeedValue: state.neededValue 
}) 

// Define mapDispatch 
const mapDispatch = (dispatch, ownProps) => { 
    return { 
    onChange: (newValue, neededValue) => { 
     dispatch(updateAttributeSelection('genre', newValue)); 
     dispatch(getTableData(newValue, ownProps.currentYear, neededValue)); 
    } 
    } 
} 

// Merge it all (create final props to be passed) 
const mergeProps = (stateProps, dispatchProps, ownProps) => { 
    return { 
    ...stateProps, // optional 
    ...dispatchProps, // optional 
    onChangeWithNeededValue: (newValue) => (
     dispatchProps.onChange(
     newValue, 
     stateProps.needeedValue // <<< here the magic happens 
    ) 
    ) 
    } 
} 

// Pass mergePros to connect 
const MyContainer = connect(mapState, mapDispatch, mergeProps)(MyComponent); 

Официальная документация: react-redux#connect

Возможный недостаток производительности на больших приложений: Stack Overflow - Performances and mergeProps in Redux