javascript - How do I change a value in an instance of a Typescript class? - Stack Overflow

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

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

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

Share Improve this question edited Dec 17, 2021 at 21:07 Aluan Haddad 31.9k10 gold badges83 silver badges95 bronze badges asked Dec 17, 2021 at 20:24 JarJar 2,0402 gold badges27 silver badges30 bronze badges 0
Add a ment  | 

2 Answers 2

Reset to default 5

Some notes:

  • React functional ponents 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)
    }
}

So, here's the thing. This isn't going to work.


First of all, any variables created in a react functional ponent's render function only exist during that render. So when you do:

let fruit = new Fruit(1, 'apple')

Then every single time your ponent renders you create a new Fruit with an id of 1 a name of "apple". Any changes you make to that object after the render will never be seen, because to be seen the ponent would need to re-rerender, which makes a new Fruit from scratch.


The way you get around this is to use "state" which preserves values between ponent renders.

So instead, let's say you had this:

const HomePage = () => {
    let [fruit, setFruit] = useState(new Fruit(1, 'apple'))
    //...
}

But the problem is that state is expected to be immutable, which means if the state were to change it expects a new object entirely, and it's forbidden to change a piece of the state.

This is because react can't tell if anything actually change in state unless you replace the state entirely.

So to fix that you would need to set a brand new object when you change the state.

This should work:

const HomePage = () => {
    let [fruit, setFruit] = useState(new Fruit(1, 'apple'))

    return (
        <div>
            {fruit.name}
            <button onClick={() => setFruit(new Fruit(fruit.id, 'banana')}>
                change the name
            </button>
        </div>
    )
}

But that's kid of annoying. This is why it's not remended to put mutable instances in state. And that means there usually isn't much need for instances of a class at all, and it's usually far simpler to just store objects in state.

// declare state
let [fruit, setFruit] = useState({ id: 1, name: 'apple' })

// set state
setFruit({ ...fruit, name: 'banana' })

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744264109a4565781.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信