1

I have multiple setState(newState, callback) statements in my Class component. Now that I'm shifting to using hooks, I am unable to put all of the callbacks in a useEffect and call them conditionally.

Some setState calls are not distinguishable with regard to what changes they are making (they may be changing the same array stored in the useState) but they all fire very different callbacks. I cannot simply just put different conditions in useState and fire callbacks.

The whole logic is becoming much more complex. How have you handled changing setState to useState without affecting the callbacks or having to make very complex logic changes inside useEffect?

Example code:

resetSelections = () => {
    const { filterData, toggleSidebarOnReset, toggleSidebar } = this.props;
    this.setState(
      {
        selections: getSelectionsFromFilterData(filterData),
      },
      () => {
        this.triggerAdvancedFilter();
        if (toggleSidebarOnReset && toggleSidebar) {
          toggleSidebar();
        }
        if (this.props.removeFilterDefaultSelection) {
          this.props.removeFilterDefaultSelection();
        }
      }
    );
  };

addCustomField = filterGroupData => {
    this.setState(
      prevState => ({
        customSelectionsMap: {
          ...prevState.customSelectionsMap,
          [filterGroupData.name]: filterGroupData.id,
        },
        selections: {
          ...prevState.selections,
          [filterGroupData.name]: [],
        },
      }),
      () => this.props.addCustomFieldInFilterData(filterGroupData)
    );
  };

removeCustomField = data => {
    const { selections, customSelectionsMap } = this.state;
    const newSelections = { ...selections };
    const newCustomSelectionsMap = { ...customSelectionsMap };
    delete newSelections[data.name];
    delete newCustomSelectionsMap[data.name];

    this.setState(
      {
        selections: newSelections,
        customSelectionsMap: newCustomSelectionsMap,
      },
      () => {
        this.props.removeCustomFieldFromFilterData(data);
        this.triggerAdvancedFilter();
      }
    );
  };

addToSelection = ({ group, name }, isReplace) => {
    const { selections } = this.state;
    if (R.contains(name, selections[group])) return null;
    const pushState = isReplace ? '$set' : '$push';
    this.setState(
      prevState => ({
        selections: update(prevState.selections, {
          [group]: { [pushState]: [name] },
        }),
      }),
      () => this.triggerAdvancedFilter()
    );
  };

Karan Sapolia
  • 482
  • 8
  • 15

1 Answers1

0

You can apply your callback implementation in useEffect by giving your state variable in dependency array

You can refer to this also How to use `setState` callback on react hooks

hassanqshi
  • 188
  • 2
  • 8
  • OP already knows that they can use `useEffect()`, their issue is that they have multiple state updates updating the same state variable, each of which trigger different callback logic. Your answer should include an explanation on the best way to handle this situation, such as a way to easily distinguish between the different state updates on the same state value. – Nick Parsons Feb 03 '22 at 22:24