Home > Software design >  Passing state as a prop in React router v6 with typescript
Passing state as a prop in React router v6 with typescript

Time:05-22

Please excuse my ignorance as I am new to React router v6 and Typescript. I am trying to pass a state and a function that will change the state down the data flow of my application.

const [playerSystem, setPlayerSystem] = useState<String>("Cheese")
      <UImaster />
    
      <Routes>
        <Route path="/sectora" element={<SectorView  {...playerSystem} /> } />
</Routes>

However when I do this if I put both playerSystem and setPlayerSystem into the props for the element it throws an error. And at the moment my SectorView component is throwing this incredibly unclear error.
Type '{ toString(): string; charAt(pos: number): string; charCodeAt(index: number): number; concat(...strings: string[]): string; indexOf(searchString: string, position?: number | undefined): number; ... 44 more ...; [Symbol.iterator](): IterableIterator<...>; }' has no properties in common with type 'IntrinsicAttributes'.
How can I pass state and state changing functions down to other components?

CodePudding user response:

Is the Props type defined in the <SectorView /> component?

CodePudding user response:

playerSystem is a string, so you cannot pass it as a prop by spreading it. The error message is listing all the properties on a string and complaining that they don't match IntrinsicAttributes, which is a confusing way of referring to the set of thing you can pass as props to an HTML element.

This is how you would pass those values as props:

<SectorView playerSystem={playerSystem} setPlayerSystem={setPlayerSystem} />

Spreading in general does work on strings, but in the case of props, I believe only objects will work because props are a set of keys and values. So, for example, this is equivalent to the above:

const [playerSystem, setPlayerSystem] = useState<String>("Cheese")
const props = { playerSystem, setPlayerSystem }

<SectorView {...props} />

Note that { playerSystem, setPlayerSystem } is shorthand for { playerSystem: playerSystem, setPlayerSystem: setPlayerSystem }.

I would guess that the reason it doesn't work at all when you try to include setPlayerSystem is you're doing {...setPlayerSystem} and you can't spread a function ever. With playerSystem it lets you do the spread because that's allowed on strings, but then SectorView has no idea what to do with it, which is why the error comes from there.

Here are examples of how spreading works (independent from JSX) with objects, strings, and arrays.

const obj1 = { a: 1 }
const obj2 = { b: 2 }

console.log({ ...obj1, ...obj2 }) // { a: 1, b: 2 }

const arr1 = [1, 2, 3]
const arr2 = [4, 5, 6]

console.log([...arr1, ...arr2]) // [1, 2, 3, 4, 5, 6]

const str1 = "ab"
const str2 = "cd"

console.log([ ...str1, ...str2]) // ["a", "b", "c", "d"]

  • Related