1

I am trying to create a handler method in React, but I'm getting a typescript error with spread operator. Could someone help with this error please? I did follow some suggestion on SO related typescript version and I installed typescript version 3.2.4. Still the error remains the same.

I get this error:

Spread types may only be created from object types.ts(2698) (parameter) prevState: string

I try to handle the onChange for form input for different useStates. This line of code works on the first input field, but not on the second, third, etc, which is why I was forced to create a handler to handle all the useStates inside. onChange= {event => setName(event.target.value)}

interface Props {
    mazeSettup: MazeSettup;
}

export const GameSettupForm: React.FC<Props> = (props:Props) => {
 const [name , setName] = useState(mazeSettup.playerName);
 const [height, setHeight] = useState(mazeSettup.mazHeight);

const handleInputChange = React.useCallback( (event: React.FormEvent<HTMLInputElement>) => {
    const name = event.currentTarget.value;

    setName((prevState) => (prevState ? {...prevState , name} : null));
 },[]);


   return (
        <Form onSubmit={handleSubmit}>
            <label htmlFor="name"> Player Name
                <input
                    type="text"
                    className="form-control"
                    id="playername"
                    name="mazeWidth"
                    placeholder="Maze Width"
                    value={mazeSettup.mazeWidth}
                    onChange= {event => setName(event.target.value)} />
            </label>

            <label htmlFor="name"> Maze Height
                <input
                    type="text"
                    name="mazeHeight"
                    placeholder="Maze Height"
                    value={mazeSettup.mazHeight}
                    onChange= {handleInputChange} />
            </label>

    )
}
Waiz
  • 503
  • 2
  • 6
  • 15
  • What are you trying to achieve? `prevState` is a string, do you want to use the spread operator on the string? – XCS Oct 08 '21 at 19:35
  • I updated my question. I simply try to handle the onChange for form input for different useStates. – Waiz Oct 08 '21 at 19:37
  • 1
    `mazeSettup.playerName` and therefore `name` state are strings. In `{...prevState , name}`, you're trying to spread a string which is throwing error. – Avinash Thakur Oct 08 '21 at 20:12
  • 1
    There is no issue of closure, and you don't need to spread, so just do -> `setName(name)` – Keith Oct 08 '21 at 20:29
  • Coud this be a valid way to do? const handleInputChange = React.useCallback( (event: React.FormEvent) => { const name = event.currentTarget.value; setName(name); setHeight(height); setWidth(width); setDifficulty(difficulty); },[height,width, difficulty]); – Waiz Oct 08 '21 at 21:09
  • 1
    You might be mixing concepts of states in functional and class components. In functional component useState hook is not a part of some global state. Each hook controls only one value you pass to that hook so prevState is not an object of all state properties, but only single property "name" in you case. – Andyally Oct 08 '21 at 21:10

1 Answers1

0

I've stumbled with this message too and the answer is on this thread: Typescript: Spread types may only be created from object types

You'll need to do as follows since spreading with a generic type isn't supported yet

function foo<T extends object>(t: T): T {
  return Object.assign({}, t);
}

At your code would be

setName((prevState) => (prevState ? Object.assign({}, prevState, name}) : null));

Apparently they say that it get corrected on version >3.2 Generic object rest variables and parameters, but I'm using typescript >4.6 and still getting the error, so maybe you could use the old way with Object assign