Состояние доступа внутри метода mapDispatchToProps
Я написал компонент контейнера с использованием redux, и моя реализация для mapDispathToProps выглядит так:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
onChange: (newValue) => {
dispatch(updateAttributeSelection('genre', newValue));
dispatch(getTableData(newValue, ownProps.currentYear));
}
}
}
Проблема в том, что для getTableData мне нужно состояние некоторых других компонентов. Как получить доступ к объекту состояния в этом методе?
Ответы
Ответ 1
Вы можете использовать redux-thunk для создания отдельной функции-создателя действия, которая имеет доступ к 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))
}
}
}
Некоторые различные способы организовать их, но что-то вроде этого должно работать.
Ответ 2
Вы можете просто использовать redux-thunk для получения состояния.
Напишите вспомогательную функцию следующим образом:
const getState = (dispatch) => new Promise((resolve) => {
dispatch((dispatch, getState) => {resolve(getState())})
})
Вы можете использовать это в функции async или функции генератора:
const mapDispatchToProps = (dispatch, ownProps) => {
return {
async someFunction() {
const state = await getState(dispatch)
...
}
}
}
Ответ 3
Возможный подход - также использовать 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);
Официальная документация: response-redux # connect
Возможный недостаток производительности в более крупных приложениях: Переполнение стека - исполнение и mergeProps в Redux