【问题标题】:Is it possible to dispatch multiple actions?是否可以调度多个动作?
【发布时间】:2021-08-17 20:11:55
【问题描述】:

当用户更改他们的国家/地区时,我正在尝试从表单中清除字段(从商店中清除状态),所以我想知道是否可以在一个事件下调度两个动作...... - 我的动作也是没有清除这些字段,所以不确定我哪里出错了

在 index.jsx 中

export default function Form() {
  const {
    apartmentNumber,
    birthDay,
    birthMonth,
    birthYear,
    buildingNumber,
    countryCode
  } = state;

  const [formData, setFormData] = useState({
    apartmentNumber,
    birthDay,
    birthMonth,
    birthYear,
    buildingNumber
  });

const onInputChange = (attribute, value) => {
    setFormData({
      ...formData,
      [attribute] : value
    });
  };

const onCountryChange = (value) => {
    dispatch(updateCountry(value));
    dispatch(clearForm(formData));
  };

在 reducer.js 中 --

export const initialState = {
  apartmentNumber           : '',
  birthDay                  : '',
  birthMonth                : '',
  birthYear                 : '',
  buildingNumber            : ''
};

export default (state, action) => {
  const { payload, type } = action;
  switch (type) {
    case UPDATE_COUNTRY:
      return {
        ...state,
        countryCode : payload
      };
    case UPDATE_FIELDS: {
      return {
        apartmentNumber : initialState.apartmentNumber,
        birthDay        : initialState.birthDay,
        birthMonth      : initialState.birthMonth,
        birthYear       : initialState.birthYear,
        buildingNumber  : initialState.buildingNumber
      };
    }
    default:
      return state;
  }
};

【问题讨论】:

  • 查看redux-thunk
  • 你为什么要使用 reducer 并且 state 好像它们是可以互换的?如果您使用 usestate 渲染组件,我认为您的组件在更改减速器状态时不会重新渲染。对于这种情况,我建议保留其中一个并在隔离组件中使用它或使用状态,但从减速器传递道具。
  • 你在你的 Rect 组件中使用了 useReducer 吗?您可以构建 reducer 来处理动作数组,在触发通过树的状态传播之前将它们应用于状态。

标签: javascript reactjs


【解决方案1】:

至于调度多个动作。您可以使用 redux,或者如果您的 reducer 没有副作用,您可以更改您的 reducer 以一次性处理这些问题。

见: Sending multiple actions with useReducers dispatch function?

如果您的输出没有副作用,您可以执行以下操作: https://codezup.com/how-to-combine-multiple-reducers-in-react-hooks-usereducer/ 我认为您不需要使用 context api,只需将 reducer 和状态传递给您要从中调用调度的组件。

如果它们有副作用,您可以通过设置一个 reducer 来实现效果链,该 reducer 返回下一个要从 useEffect 运行的效果,如果您需要在每次调度中更改 ui,这很有用。对于多种效果,您可以将它们组合起来,然后在一个 useEffect 中运行。

除此之外,像 redux 这样的库基本上是开箱即用的。但是我从来没有用过redux。

【讨论】:

    【解决方案2】:

    您可以重置在 initialState 中传递的值。理想情况下,您应该在UPDATE_COUNTRY 成功时执行操作。然后,一旦国家/地区成功更新,您就可以重置为 initialState。

        case UPDATE_COUNTRY_SUCCESS:
            return initialState;
    

    或者如果您不想添加成功操作,您可以这样做

        case UPDATE_COUNTRY:
            return {
              ...initialState,
              countryCode: payload
            };
    
    

    【讨论】:

      【解决方案3】:

      你可以使用 useReducer React 钩子来做到这一点。请注意 createReducer 函数以及如何组合它来处理动作数组。

      const createReducer = (actions, state) {
          return (state, action) => {
              if(Array.isArray(action)) {
                  actions.forEach(action => {
                      state = actions[action[i].type](state, action[i])
                  })
                  return state
              } else if(actions[action.type]) {
                  return actions[action.type](state, action)
              } else {
                  return state
              }
          }
      }
      
      const actions = {
        INCREMENT: (state, action) => {
          state.counter++
          return state
        }
      }
      
      const initState = () => ({
        counter: 0
      })
      
      const reducer = createReducer(actions)
      
      const App = () => {
        const [state, setState] = React.useReducer(reducer, initState())
        return <div>Count: {state.count} 
          <button onClick={e => setState([
            {type: 'INCREMENT'},
            {type: 'INCREMENT'}
          ])}>+</button>
        </div>
      }
      

      我怀疑您的问题是状态正在通过 DOM 树传播,每个操作都已调度,这可能导致 DOM 状态损坏或奇怪。使用这种架构,您可以在状态返回之前应用数组中的每个操作,这意味着只有在所有操作都应用到状态后才会进行传播。

      【讨论】:

        猜你喜欢
        • 2018-05-31
        • 2019-10-17
        • 1970-01-01
        • 2018-12-10
        • 2022-01-26
        • 2023-02-20
        • 2015-05-05
        • 2020-12-20
        • 2020-12-31
        相关资源
        最近更新 更多