Search code examples
javascriptreactjstypescriptes6-classreact-typescript

How do I change a value in an instance of a Typescript class?


I have a Fruit class:

export class Fruit {
    constructor(public id: number, public name: string) {}

    public changeName(_name: string): void {
        console.log('changing name')
        this.name = _name
    }
}

And I implement it like so:

import React from 'react'
import { Fruit } from '../classes/fruit'

const HomePage = () => {
    let fruit = new Fruit(1, 'apple')

    return (
        <div>
            {fruit.name} <----- I am expecting this to update on the DOM when i click the button *********
            <button onClick={() => fruit.changeName('banana')}>
                change the name
            </button>
        </div>
    )
}

export default HomePage

But when I click the button, the fruit name on the screen does not change. It stays as 'apple' . Does anyone know what I am doing wrong? I am new to Typescript


Solution

  • Some notes:

    • React functional components do not work like that. If your data changes over time, you need to define some state, with a hook: const [fruit, setFruit] = React.useState(initialFruit).

    • That still won't work, as your fruit is a mutable object, React does not "see" in-place imperative updates. Not ideal, but you could fool React by using an object wrapper as the state value: { value: someFruit } (this works because in JS { value: 1 } !== { value: 1 }.

    • Consider writing classes with immutable setters (public changeName(name: string): Fruit), and you'll be able to write nice declarative code like this: <button onClick={() => setFruit(fruit.changeName('banana'))}>.

    export class Fruit {
        constructor(public id: number, public name: string) {}
    
        public changeName(name: string): Fruit {
            return new Fruit(this.id, name)
        }
    }