2

I am just trying to figure out how to use prevState in the useState hook with React typescript. The button are mapped using the data from the objectData.

So far I have:

let data = dataFromFile;

const [chart, setChart] = React.useState<ChartInterface[]>(data);

in the component I am doing:

export interface ActiveObject {
    id: number;
    title: string;
    cb: (idx: number) => void;
};

export interface ButtonGroupState {
    activeObject: ActiveObject | null;
    objects: ActiveObject[];
};

export interface ButtonGroupProps {
    data: Array<ActiveObject> 
}

   const ObjectData: ActiveObject[] = [
        {
            id: 1,
            title: "1 way day",
            cb: () => { setChart(prevState => prevState.set(Data7Day)) }
        },
    ];

But that does not really work, any idea's? I get Property 'set' does not exist on type 'ChartInterface[]'. I know thats to do with the interface, but is that the way to do use PrevState in useState and is it needed at all?

Sole
  • 3,100
  • 14
  • 58
  • 112
  • based on `chart`'s type (ChartInterface[]), `chart` is an array. In the `cb` function, you're trying to use `.set` on an array. Add what `cb` should actually do to the question. – Ramesh Reddy Oct 05 '21 at 15:46
  • @ABDULLOKHMUKHAMMADJONOB No, we return the updated state inside the callback, not call `setState` again. – Ramesh Reddy Oct 05 '21 at 15:48
  • Not sure why you are using `.set` at all, doesn't make sense. That's not how React works. – Dan Zuzevich Oct 05 '21 at 15:48
  • I have seen .set has been used in other questions as the answer.... https://stackoverflow.com/questions/55823296/reactjs-prevstate-in-the-new-usestate-react-hook – Sole Oct 05 '21 at 15:51
  • Like I said, I am unsure on how to use this, thats why I am asking the question - so if its not correct its because I am unsure, this is just an approach i have tried – Sole Oct 05 '21 at 15:52
  • @RameshReddy CB function should update state based on previous state. The chart data is an array of objects. I mean the question is do I need to even update state based on previous state for this scenario? – Sole Oct 05 '21 at 22:14

1 Answers1

3

According to the docs:

If the new state is computed using the previous state, you can pass a function to setState. The function will receive the previous value, and return an updated value. Here’s an example of a counter component that uses both forms of setState:

function Counter({initialCount}) {
  const [count, setCount] = useState(initialCount);
  return (
    <>
      Count: {count}
      <button onClick={() => setCount(initialCount)}>Reset</button>
      <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button>
      <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    </>
  );
}

So, basically what that means is that you can also pass a function to the setter function returned by the useState Hook.

You need to pass the argument as function, when you need to set the next state, on basis of the current one. As @RameshReddy pointed, if cb function should just change the chart array to a new array called Data7Day, you don't need to use a functional state update, you can directly call setChart(Data7Day)

for ex...

const [count, setCount] = useState(0);

setCount(c => c + 1) is better than setCount(count + 1)

Shivam Jha
  • 3,160
  • 3
  • 22
  • 36
  • `setChart(prevChartValue => prevChartValue = Data7Day) / setChart(prevChartValue => prevChartValue = Data1Day)` Would this be right to changing the data state from one to another? Data structure is an array – Sole Oct 05 '21 at 22:21
  • You want to replace entire current state (`prevChartValue`) with `Data7Day`(an array), or want to add something to that array ? – Shivam Jha Oct 06 '21 at 04:00
  • Correct update previous vale of chart to new value which is `Data7Day` this will be from an api ultimately but at the moment is from a hard coded file – Sole Oct 06 '21 at 08:35
  • 1
    @Sole if cb function should just change the chart array to a new array called `Data7Day`, you don't need to use a functional state update, you can directly call `setChart(Data7Day)` – Ramesh Reddy Oct 06 '21 at 08:39
  • @RameshReddy Thanks, thats what I have been asking all along. Can you just explain when prev state would be valid to use? would it only be used for things like counters etc? – Sole Oct 06 '21 at 08:48
  • @Sole Whenever the new state depends on the old state you can use the functional update. The state doesn't necessarily have to be counter or anything specific. Go through the linked questions. – Ramesh Reddy Oct 06 '21 at 10:13
  • @Sole Now I know what you desire, RameshReddy is right. I have updated the answer accordingly – Shivam Jha Oct 06 '21 at 10:37