最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to dispatch after setstate - Stack Overflow

programmeradmin1浏览0评论

I want to dispatch an action which depends on a previously set state in a functional ponent. 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));
}

I want to dispatch an action which depends on a previously set state in a functional ponent. 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));
}
Share Improve this question edited Jul 21, 2021 at 19:07 Emile Bergeron 17.4k5 gold badges85 silver badges131 bronze badges asked Jul 21, 2021 at 18:34 SimonSimon 6617 silver badges21 bronze badges 2
  • What you have there will work just fine. state in that context is the previous state. – Benjamin Commented Jul 21, 2021 at 18:36
  • 1 Note that setState doesn't return a promise, so using await only creates a race-condition. – Emile Bergeron Commented Jul 21, 2021 at 19:08
Add a ment  | 

2 Answers 2

Reset to default 5

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 mitting 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} />;
};
发布评论

评论列表(0)

  1. 暂无评论