1

I am new to type script and I am trying to set the state in react using use state hook and type script.

const intialState: State ={
    items: [],
    value: "",
    error: null
}

const [data, setData]= useState([intialState]);

return (
    <>
        {
            data.items.map(x) => (
                //my html component to be displayed.
            )
        }
    </>
)

but I am getting the below error. Can any one tell me.

  1. Is it valid to set an object inside a usestate like I have done?
  2. Why I am getting the typescript error?

enter image description here

Rakesh
  • 65
  • 1
  • 9
  • What does your State type look like? The error was basically saying your State type(interface, class) does not have a property called items – wctiger May 09 '20 at 15:00
  • actually I an trying to crate a new state as empty object so what type shall i define there? is object a valid type? – Rakesh May 09 '20 at 15:03
  • Can we see how `State` look like? – wentjun May 09 '20 at 15:08
  • **See Also**: [Set types on useState React Hook with TypeScript](https://stackoverflow.com/q/53650468/1366033) – KyleMit Jun 17 '21 at 21:12

3 Answers3

2

First, we should check if there is an interface mismatch between State, and the initialState object. It will help if you can post the type definition of State.

In addition, you should supply the useState hook with the generic type parameter of State[]

const [data, setData]= useState<State[]>([intialState]);
wentjun
  • 40,384
  • 10
  • 95
  • 107
1

You need to specify type for useState. Since its an array of your state object you can write it like

const [data, setData]= useState<State[]>([intialState]);

Also make sure you define a type for your state's object

interface ErrorType {
   status: Number // more keys and their types here
}
interface MyDataType {
  items: ItemType[],
  error: ErrorType | null,
  value: string,
}

post that you can use it with useState like

const [data, setData]= useState<MyDataType[]>([intialState]);

Your data is an array of objects and when you update the state you need to merge the values. For that you can use functional setState

var updatedDataObj = { items: ["a","b","c"], error: "404", value: "xyx", };
setData(prevData => [...prevData, updatedDataObj]);
Shubham Khatri
  • 270,417
  • 55
  • 406
  • 400
  • Thanks your your response can you please show me what is the syntax to setData with multiple objects. var updatedDataObj = { items: ["a","b","c"], error: "404", value: "xyx", }; setData(updatedDataObj); is this correct? – Rakesh May 09 '20 at 15:32
  • Do you want to merge the objects or just replace them. Also data is an array of object so I am assuming you want to add more objects to it. Is that correct? Or do you just want to store an object in state instead of an array of objects? – Shubham Khatri May 09 '20 at 15:34
  • yes...I want to add more object to that . So basically I am trying to convert https://codesandbox.io/embed/ypyxr11109 this example into a reusable component using usestate hook – Rakesh May 09 '20 at 15:36
  • I updated my answer according to that. Please check – Shubham Khatri May 09 '20 at 15:37
  • Can you please provide a small snippet for the above example or a fiddle using usestate. – Rakesh May 09 '20 at 15:37
  • I couldnt find any change in this fiddle codesandbox.io/embed/ypyxr11109 – have you done any chagnes here? – Rakesh May 09 '20 at 17:08
  • Ohh I think I didn't save it. Let me update it again – Shubham Khatri May 09 '20 at 17:48
  • I had to make a new one. https://codesandbox.io/s/frosty-cloud-h270z?file=/src/App.js – Shubham Khatri May 09 '20 at 17:56
  • Hi at this line setState(prev => ({ ...prev, items: [...prev.items, prev.value], value: "" })); I am getting an error in my code as argument of type is not assignable to parameter of type set state action. Can you please tell me what is wrong here? – Rakesh May 09 '20 at 18:12
1

I guess this was what you tried to achieve. Make sure you define your State type correctly, not importing from some other packages

interface State {
    items: any[];
    value: string;
    error: string | null;
}


const MyComponent: (props) => {
    const intialState: State ={
        items: [],
        value: "",
        error: null
    }
    const [data, setData] = useState(intialState)


return (
   <>
        {
            data.items.map(x) => (
                //my html component to be displayed.
            )
        }
    </>
    )
}
wctiger
  • 921
  • 12
  • 22