Josh Merrian
Josh Merrian

Reputation: 321

Accessing the "this" keyword in a React state object

I have a usestate object, like so:

const [state, setState] = React.useState({
    firstName: "John",
    lastName: "Doe",
    id: "12345",
    getFullName():any {
      return `${this.firstName} ${this.lastName}`;
    },
  });


...

return (
  <button onClick={() => console.log(state.getFullName())}></button>
)

However, when I try to run the getFullName method, TypeScript throws an error:

Property 'firstName' does not exist on type '{ firstName: string; lastName: string; id: string; getFullName(): any; } | (() => { firstName: string; lastName: string; id: string; getFullName(): any; })'.

Also, if I ignore this TS warning, I still get a can't read property 'firstName' of undefined error

What can I do to get it to work?

Upvotes: 2

Views: 202

Answers (2)

Lesiak
Lesiak

Reputation: 25976

The problem lies in the function useState, which can accept either initialState or a function producing it:

function useState<S>(initialState: S | (() => S)): [S, Dispatch<SetStateAction<S>>];

To fix, extract initalState to a separate object:

const initialState = {
    firstName: "John",
    lastName: "Doe",
    id: "12345",
    getFullName():string {
    return `${this.firstName} ${this.lastName}`;
  },
};

const [state, setState] = React.useState(initialState);

Playground link

Also, consider using an IIFE for constructing the initialState:

const initialState = ((firstName, lastName) => ({
    firstName,
    lastName,
    id: "12345",
    getFullName():string {
    return `${firstName} ${lastName}`;
  },
}))('John', 'Doe');

Upvotes: 1

Nikita Mazur
Nikita Mazur

Reputation: 1785

You can just put it into separate function, its a bad idea to access "this" in functional components

const [state, setState] = React.useState({
firstName: "John",
lastName: "Doe",
id: "12345"});

const getFullName = () => {
    return `${state.firstName} ${state.lastName}`
}

Upvotes: 2

Related Questions