Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

133
Views
Keep getter function in sync with an object's current state in React/TypeScript

WHAT I HAVE

I have a Parent class and a Child class.

export class Parent {
    properties: { x: number};
    child: Child;
    constructor() {
        this.properties = {
            x: 1
        }
        this.child = new Child(this.getX);
    }
    getX = () => {
        return this.properties.x;
    }
}

class Child {
    parent_getX:()=>string
    constructor(parent_getX:()=>string){
        this.parent_getX = parent_getX;
    }
}

The Parent class has:

  • a field called properties which stores an number value called x.
  • a function called getX() which simply pulls the value of x from within the properties object.
  • a field called child which holds a reference to a Child object.

The Child class only receives a reference to the Parent's getX() function.

WHAT I WANT

My goal is to be able to update the value of x and that everytime I call child.parent_getX() or parent.getX() I get the latest value of x.

WHAT I'M SEEING

I have a React component called Example that takes a Parent object with a an x value of 1 as initial state.

Whenever I increment this value using setState(...) the value of x is incremented but for some reason, parent.getX() and parent.child.parent_getX() always keeps returning the initial value of x. What can I do to keep the function in sync with the parent object?

export const Example = () => {

    const [parent, setParent] = useState(new Parent());

    const incrementX = ()=>{
        let newParent = { ...parent, properties: { ...parent.properties, x: parent.properties.x + 1 } }
        setParent(newParent);
    }

    return (<>
        <p>
            Parent.properties.x = {parent.properties.x}
            <br/>
            Parent.getX() = {parent.getX()}
            <br/>
            Parent.child.parent_getX() = {parent.child.parent_getX()}
        </p>
        <button onClick={incrementX}>
            Increment
        </button>
    </>);
}
about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

The reason that you are seeing the old values is that in incrementX() you create a copy of the existing Parent instead of instantiating a new one with new (). Therefore, the existing instance of Child (which references the old parent's getX() function) is copied over, as opposed to being instantiated in Parent's constructor. Similarly, the getX() method itself is copied over with it's this referencing the old parent (because it is a fat arrow function, the this reference does not change).

The most straightforward way to fix this is to add a copy constructor to Parent and use that instead of the spread syntax:

export class Parent {
    properties: { x: string};
    child: Child;
    constructor(source?: Parent) {
        this.properties = {
            x: '1'
        }

        this.child = new Child(() => this.getX());

        if (source) {
            this.properties = {...source.properties};
            // any additional copy logic goes here
        }
    }

    getX() {
        return this.properties.x;
    }
}

Then use that copy constructor in your component:

    const incrementX = () => {
        let newParent = new Parent(parent);
        newParent.properties.x = newParent.properties.x + 1;
        setParent(newParent);
    }

Note that an even easier solution would be to not copy the original Parent at all, and just increment its properties.x, but I'm assuming you need a new instance for the state change to be detected.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!