Problem typing first parameter of React setState

Asked

Viewed 170 times

2

Hello, I’m a little new to the typescript world and there’s something going on that I can’t explain why.

I have the following state:

const [estaExecutando, mudarExecucao] = useState(false);

Step to my component as follows:

<Contador
   tempo_total={tempoTotal}
   estaExecutando={estaExecutando}
   mudarExecucao={mudarExecucao}
/>

So within that component I have the following interface and implementation:

interface ContadorProps {
  tempo_total: number;
  estaExecutando: Boolean;
  mudarExecucao: (prev: boolean) => boolean; // Vai receber no prev o estado anterior que no caso seria true ou false e vai retornar também true ou false
}

const Contador: React.FC<ContadorProps> = ({ tempo_total, estaExecutando, mudarExecucao }) => {
    <TouchableOpacity onPress={() => mudarExecucao((prev: boolean) => !prev)}>
       Play/pause
    </TouchableOpacity>
}

That gives me the following mistake:

Argument of type '(Prev: Boolean) => Boolean' is not Assignable to Parameter of type 'Boolean'.

I have tried to put in the interface that this function returns void. I’ve also tried to get Boolean out of the EV

<TouchableOpacity onPress={() => mudarExecucao((prev) => !prev)}>

But still the same mistake. What am I doing wrong?

1 answer

3


This happens because the setState is much more than a simple function that returns only a boolean. In the variables of useState, the second element (mudarExecucao) is a function of the type Dispatch<SetStateAction<boolean>> where it takes a boolean parameter, in this case prev, and returns nothing.

In fact, the function setState returns nothing, then you set the type :

mudarExecucao: (prev: boolean) => boolean;

for a function of the type setState will make Typescript release this error.

How to solve this...

In your file where we have the Contador, we will import the SetStateAction:

import React, { SetStateAction } from 'react';

...

Now on the interface ContadorProps, let’s define the function type mudarExecucao as React.Dispatch<SetStateAction<boolean>>.

Let’s see below:

interface ContadorProps {
  tempo_total: number;
  estaExecutando: Boolean;
  mudarExecucao: React.Dispatch<SetStateAction<boolean>>;
}

Notice that React.Dispatch<SetStateAction<boolean>> I passed by boolean, because it is the type of the parameter prev.

Giving an overview of what the file should look like (more or less) Contador:

import React, { SetStateAction } from 'react';
import { TouchableOpacity, View, Text } from 'react-native';

interface ContadorProps {
  tempo_total: number;
  estaExecutando: Boolean;
  mudarExecucao: React.Dispatch<SetStateAction<boolean>>;
}

const Contador: React.FC<ContadorProps> = ({
  tempo_total,
  estaExecutando,
  mudarExecucao
}) => {
  // ...
  return (
    <View>
      <TouchableOpacity onPress={() => mudarExecucao((prev: boolean) => !prev)}>
        <Text>Play/pause</Text>
      </TouchableOpacity>
    </View>
  );
};

export default Contador;

About the Dispatch

It is simply defined as (valor: V) => void, a function that receives a value and returns nothing.

About SetStateAction

SetStateAction<S> is defined as:

S | ((prevState: S) => S)

Therefore, the type of Dispatch<SetStateAction<S>> is actually:

(value: S | ((prevState: S) => S)) => void

a function that gets an updated version of state or a function that plays the updated version based on the previous version of state ((prevState: S) => S). In both cases, we can deduce that the second element returned by setState is a function we can call to update the state of the component.

In short....

Dispatch<SetStateAction<S>> is the type that should be declared for a function that changes a React state (setState) and S represents the Generic of the type of the parameter reported.

  • It worked perfectly, it was worth a lot! I didn’t know I needed a specific type for this. Has other React functions that need specific typing as well?

  • would have to consult the documentation to see the type of each action of a React hook, but I believe each one has a specific type for each action.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.