developer tip

Redux 감속기 내부의 상태에 액세스하는 방법은 무엇입니까?

copycodes 2020. 11. 18. 09:18
반응형

Redux 감속기 내부의 상태에 액세스하는 방법은 무엇입니까?


감속기가 있고 새로운 상태를 계산하려면 작업의 데이터 와이 감속기가 관리하지 않는 상태의 일부의 데이터가 필요합니다. 특히 아래에 보여줄 감속기에서 accountDetails.stateOfResidenceId필드에 대한 액세스 권한이 필요 합니다.

initialState.js :

export default {
    accountDetails: {
        stateOfResidenceId: '',
        accountType: '',
        accountNumber: '',
        product: ''
    },
    forms: {
        blueprints: [

        ]
    }
};

formsReducer.js :

import * as types from '../constants/actionTypes';
import objectAssign from 'object-assign';
import initialState from './initialState';
import formsHelper from '../utils/FormsHelper';
export default function formsReducer(state = initialState.forms, action) {
  switch (action.type) {
    case types.UPDATE_PRODUCT: {
        //I NEED accountDetails.stateOfResidenceId HERE
        console.log(state);
        const formBlueprints = formsHelper.getFormsByProductId(action.product.id);
        return objectAssign({}, state, {blueprints: formBlueprints});
    }

    default:
      return state;
  }
}

index.js (루트 감속기) :

import { combineReducers } from 'redux';
import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';

const rootReducer = combineReducers({
    accountDetails,
    forms
});

export default rootReducer;

이 필드에 어떻게 액세스 할 수 있습니까?


이를 위해 썽크사용 합니다. 여기에 예가 있습니다.

export function updateProduct(product) {
  return (dispatch, getState) => {
    const { accountDetails } = getState();

    dispatch({
      type: UPDATE_PRODUCT,
      stateOfResidenceId: accountDetails.stateOfResidenceId,
      product,
    });
  };
}

기본적으로 작업에 필요한 모든 데이터를 얻은 다음 해당 데이터를 감속기로 보낼 수 있습니다.


옵션은를 사용하는 것 외에 더 많은 논리를 작성 combineReducers하거나 작업에 더 많은 데이터를 포함하는 것입니다. Redux FAQ는이 주제를 다룹니다 : http://redux.js.org/docs/faq/Reducers.html#reducers-share-state .

또한 저는 현재 "Structuring Reducers"라는 주제에 대한 Redux 문서의 새로운 페이지 세트를 작업 중이며 도움이 될 것입니다. 현재 WIP 페이지는 https://github.com/markerikson/redux/blob/structuring-reducers-page/docs/recipes/StructuringReducers.md에 있습니다.


나는 당신이 그것을 액션 크리에이터에게 넘겨 주길 권합니다. 따라서 어딘가에 다음과 같은 작업을 수행하는 액션 제작자가 있습니다.

updateProduct(arg1, arg2, stateOfResidenceId) {
  return {
    type: UPDATE_PRODUCT,
    stateOfResidenceId
  }
}

액션을 트리거하는 곳에서 react를 사용한다고 가정하면

function mapStateToProps(state, ownProps) {
  return {
    stateOfResidenceId: state.accountdetails.stateOfResidenceId
  }  
}

react-redux의 연결을 사용하여 반응 구성 요소에 연결하십시오.

connect(mapStateToProps)(YourReactComponent);

이제 updateProduct 작업을 트리거하는 반응 구성 요소에서 stateOfResidenceId를 소품으로 가져야하며이를 작업 작성자에게 전달할 수 있습니다.

복잡하게 들리지만 실제로는 우려의 분리에 관한 것입니다.


다음을 사용해 볼 수 있습니다.

redux-named-reducers

이렇게하면 코드의 어느 곳에서나 상태를 얻을 수 있습니다.

const localState1 = getState(reducerA.state1)
const localState2 = getState(reducerB.state2)

그러나 액션의 페이로드로 외부 상태를 전달하는 것이 더 나은지 먼저 생각하십시오.


이 접근 방식이 안티 패턴인지 확실하지 않지만 저에게 효과적이었습니다. 당신의 행동에 카레 기능을 사용하십시오.

export const myAction = (actionData) => (dispatch, getState) => {
   dispatch({
      type: 'SOME_ACTION_TYPE',
      data: actionData,
      state: getState()
   });
}

원하는 것을 정확히 수행하는 결합 함수를 작성하는 것은 간단합니다.

import accountDetails from './accountDetailsReducer';
import forms from './formsReducer';

const rootReducer = (state, action) => {
        const newState = {};

        newState.accountDetails = accountDetails(state.accountDetails, action);
        newState.forms = forms(state.forms, action, state.accountDetails);

        return newState;
    };

export default rootReducer; 

FormReducer는 다음과 같습니다.

export default function formsReducer(state = initialState.forms, action, accountDetails) {

이제 formsReducer가 accountDetails에 액세스 할 수 있습니다.

이 접근 방식의 이점은 전체 상태가 아니라 필요한 상태 조각 만 노출한다는 것입니다.


An alternative way, if you use react-redux and need that action only in one place OR are fine with creating an HOC (Higher oder component, dont really need to understand that the important stuff is that this might bloat your html) everywhere you need that access is to use mergeprops with the additional parameters being passed to the action:

const mapState = ({accountDetails: {stateOfResidenceId}}) => stateOfResidenceId;

const mapDispatch = (dispatch) => ({
  pureUpdateProduct: (stateOfResidenceId) => dispatch({ type: types.UPDATE_PRODUCT, payload: stateOfResidenceId })
});

const mergeProps = (stateOfResidenceId, { pureUpdateProduct}) => ({hydratedUpdateProduct: () => pureUpdateProduct(stateOfResidenceId )});

const addHydratedUpdateProduct = connect(mapState, mapDispatch, mergeProps)

export default addHydratedUpdateProduct(ReactComponent);

export const OtherHydratedComponent = addHydratedUpdateProduct(OtherComponent)

When you use mergeProps what you return there will be added to the props, mapState and mapDispatch will only serve to provide the arguments for mergeProps. So, in other words, this function will add this to your component props (typescript syntax):

{hydratedUpdateProduct: () => void}

(take note that the function actually returns the action itself and not void, but you'll ignore that in most cases).

But what you can do is:

const mapState = ({ accountDetails }) => accountDetails;

const mapDispatch = (dispatch) => ({
  pureUpdateProduct: (stateOfResidenceId) => dispatch({ type: types.UPDATE_PRODUCT, payload: stateOfResidenceId })
  otherAction: (param) => dispatch(otherAction(param))
});

const mergeProps = ({ stateOfResidenceId, ...passAlong }, { pureUpdateProduct, ... otherActions}) => ({
  ...passAlong,
  ...otherActions,
  hydratedUpdateProduct: () => pureUpdateProduct(stateOfResidenceId ),
});

const reduxPropsIncludingHydratedAction= connect(mapState, mapDispatch, mergeProps)

export default reduxPropsIncludingHydratedAction(ReactComponent);

this will provide the following stuff to the props:

{
  hydratedUpdateProduct: () => void,
  otherAction: (param) => void,
  accountType: string,
  accountNumber: string,
  product: string,
}

On the whole though the complete dissaproval the redux-maintainers show to expanding the functionality of their package to include such wishes in a good way, which would create a pattern for these functionalities WITHOUT supporting fragmentation of the ecosystem, is impressive.

Packages like Vuex that are not so stubborn dont have nearly so many issues with people abusing antipatterns because they get lost, while supporting a way cleaner syntax with less boilerplate than you'll ever archive with redux and the best supporting packages. And despite the package being way more versatile the documantation is easier to understand because they dont get lost in the details like reduxs documentation tends to do.


While dispatching an action, you can pass a parameter. In this case, you could pass accountDetails.stateOfResidenceId to the action and then pass it on to the reducer as payload.

참고URL : https://stackoverflow.com/questions/39257740/how-to-access-state-inside-redux-reducer

반응형