Подтвердить что ты не робот

Состояние доступа внутри метода mapDispatchToProps

Я написал компонент контейнера с использованием redux, и моя реализация для mapDispathToProps выглядит так:

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

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

4b9b3361

Ответ 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