Как получить доступ к магазину редуксов от создателя экшена? - PullRequest
0 голосов
/ 29 января 2019

Я пытаюсь объединить действия.В моей текущей проблеме, когда происходит действие SET_CURRENT_USER, я бы хотел, чтобы оно изменило состояние (установило текущего пользователя), а затем запустило кучу других побочных эффектов (извлечение данных, перестройка пользовательского интерфейса и т. Д.).Моей первой мыслью было: «Хорошо, я назначу слушателя в магазине» ... что привело к этому предыдущему вопросу: Как получить доступ к «магазину» в реагирующем редуксе?(или как связывать действия) Там я был в основном так, что установка слушателей является анти-паттерном.

Предложенное решение состояло в том, чтобы «распределить» несколько действий, связанных вместе.Я не следил за тем, как это сделать (мой «mapDispatchToProps» основан на уроках с избыточностью и не похож на предложенный mapDispatchToProps), поэтому я сделал несколько дополнительных поисков по поводу того, как объединить побочные действия вместе, и попал на эту страницу: https://goshakkk.name/redux-side-effect-approaches/

В первом примере я перешел к файлу создателя действий, который выглядит следующим образом:

(actionCreators.js)

export function setCurrentUser(username) {
    return { type: SET_CURRENT_USER, payload: username }
}

export function actionTwo(username) {
    return { type: ACTION_TWO, payload: username }
}

export function actionThree(username) {
    return { type: ACTION_THREE, payload: username }
}

и я попыталсяизмените создатель действия 'setCurrentUser' на что-то похожее на то, что было в демонстрации, но без асинхронных частей для простоты - просто посмотрите, не запускаются ли действия:

export function setCurrentUser(username) {
    return dispatch => {
        dispatch( { type: SET_CURRENT_USER, payload: username } );
        dispatch( { type: ACTION_TWO, payload: username } );
        dispatch( { type: ACTION_THREE, payload: username } );
    }
}

В моем приложении мой mapDispatchToProps выглядит следующим образом:

const mapDispatchToProps = {
    setCurrentUser: setCurrentUser,
}

, и я вызываю это в обработчике switchUser, например: this.props.setCurrentUser(this.state.newUsername);

... и получаю сообщение об ошибке, в котором действия должны быть простыми объектами.

Как я могу связать действия вместе?

Возможно, более глубокая проблема заключается в том, что я не знаю, как получить доступ к хранилищу, чтобы иметь возможность вызывать store.dispatch.(который был моим предыдущим вопросом, отмеченным выше)

Ответы [ 5 ]

0 голосов
/ 29 января 2019

Redux Thunk был бы идеальным способом сделать это, но вы все равно можете цепочки действий, возвращая обещания в качестве полезной нагрузки. (Если вы не хотите использовать Thunk)

export function setCurrentUser(username) {
    return { 
      type: SET_CURRENT_USER, 
      payload: new Promise(resolve => resolve(username))  
    }
} 

export function actionTwo(username) {
    return { 
      type: ACTION_TWO, 
      payload: new Promise(resolve => resolve(username))  
    }
}

export function actionThree(username) {
    return { 
      type: ACTION_THREE, 
      payload: new Promise(resolve => resolve(username))  
    }
}

И тогда вы можете позвонитьвсе три как:

this.props.setCurrentUser(this.state.newUsername)
 .then(newUsername => this.props.actionTwo(newUsername))
 .then(newUsername => this.props.actionThree(newUsername))
0 голосов
/ 29 января 2019

я не могу оставить комментарий, поэтому вопрос: почему вы просто не установите mapState и не передадите состояние в качестве аргумента отправляемому действию?

Вот компоненты компонента

class AComponent extends Component{
     ...
     ... onClick={()=>this.props.anAction(this.props.state)}
}

const mapStateToProps = state => {
    return { state: state.YourReducer }
}

const mapDispatchToProps = dispatch => {
    return { anAction: () => dispatch(actions.doAnyStaffWith(state)) }
}

export default connect(mapStateToProps, mapDispatchToProps)(BeerReviewer)

файл действий:

export function actionThree(state) {
     return { type: ACTION_TYPE, state }
}

Это то, что вы ищете?

0 голосов
/ 29 января 2019

Вы должны иметь возможность получить доступ к вашему магазину, как это (иллюстрация с запросом на выборку):

import { someAPICALL } from '../api'

export function setCurrentUser(username) {
    return async (dispatch, getState) => {
        const { yourStateVariable } = getState().YourReducer
            , data = await someAPICall(yourStateVariable)
                           .catch(e => dispatch({ type: FETCH_ERROR, payload: e }))

        if (data) {
          dispatch( { type: SET_CURRENT_USER, payload: username } );
          dispatch( { type: ACTION_TWO, payload: username } );
          dispatch( { type: ACTION_THREE, payload: username } );
        } else {
          dispatch( { type: SOME_OTHER_ACTION, payload: 'whatever state update you like' } )
        }
    }
}
0 голосов
/ 29 января 2019

Вам понадобится танк, чтобы усилить своих создателей действий.причина, по которой вы получаете ошибку «должны быть обычными объектами», заключается в том, что создатель вашего действия возвращает функцию (), а не объект.Thunk позволяет вам возвращать функции создателям ваших действий, и с этим написанный код должен работать.

import { createStore, combineReducers, applyMiddleware } from "redux"
import thunk from "redux-thunk"

const store = createStore(combineReducers({
     data1: reducer1,
     data2: reducer2
}), {}, applyMiddleware(thunk))

Надеюсь, что это работает.

0 голосов
/ 29 января 2019

Я думаю, вы mapDispatchToProps функция должна выглядеть следующим образом: const mapDispatchToProps = { setCurrentUser: (data) => dispatch(setCurrentUser(data)), }.Что касается доступа к хранилищу от создателей ваших действий, вам нужно экспортировать его из того места, где вы его объявили (index.js).импортируйте его в файл actionCreators, а затем используйте его там.Это происходит следующим образом: в файле index.js: export const store = createStore(...) и в вашем файле actionCreators: import { store } from "your index.js file's path" и все готово.Надеюсь, что это решит вашу проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...