简体   繁体   中英

How to dispatch after setstate

I want to dispatch an action which depends on a previously set state in a functional component. What are my options?

<Buton 
  onPress={() => {
  setState(state + 1);
  dispatch(myAction(state));
        }}
/>

Edit: For clarity, I mean that the dispatched state is dependent on state being set previously. In pseudo code:

async () => {
   await setState(state + 1);
   dispatch(myAction(state));
}

If you want to dispatch an action when state changes (using the new value), you probably want to use useEffect :

useEffect(() => {
    dispatch(myAction(state))
}, [state])

<Buton 
    onPress={() => {
        setState(state + 1);
    }}
/>

Edit: Updating my answer with a better approach.

The goal is to setState, and then call a function with the previousState as an argument. In order to do that, let's write a custom hook to encapsulate that goal.

Our custom hook will initialize a useState hook, and return state, and a custom wrapped setState method.

When the custom setState method is called with a callback argument, we will push that callback into an array and save it to a ref.

Next we write a useEffect hook that will be called after React has finished committing any state changes.

Inside our useEffect hook we will call each of the callbacks in our ref list passing the previousState and nextState as arguments.

After the callbacks are finished, we clear the callbacks list and save the currentState to the previousState ref.

useStateWithCallback.js

import React, { useState, useRef, useEffect } from 'react';

export const useStateWithCallback = (initialState) => {
  const [state, setState] = useState(initialState);

  const previousState = useRef(initialState);
  const myCallbacksList = useRef([]);

  const setStateWithCallback = (state, callback) => {
    setState(state);
    if (callback) {
      myCallbackList.current.push(callback);
    }
  };

  useEffect(() => {
    myCallbacksList.current.forEach((callback) => callback(previousState.current, state));
    myCallbacksList.current = [];
    previousState.current = state;
  }, [state]);

  return [state, setStateWithCallback];
};
import React from 'react';
import { useStateWithCallback } from './useStateWithCallback';

const Example = (props) => {
  const [state, setState] = useStateWithCallback();

  const handlePress = () => {
    setState(
      (prevState) => prevState + 1,
      (prevState, currentState) => dispatch(myaction(prevState))
    );
  };

  return <Buton onPress={handlePress} />;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM