3

I am trying to render an parent-component which has two children. The rendering of the children will switch, so one time there will be only the first child rendered, another time it will be the last and finally it will switch back to the first child (which then should contain all the values shown before). I thought this would be simple but it turned out that it is not.

Now to the problem: Whenever the method switchContainer is called, it will switch the container and render the other. However all member-variables, props and states are getting lost and it basically reinstanciated the child-component from scratch.

Is there a way to save the child-components "as-is" and once it is getting re-rendered, it will hold all the member-variables, props and states again?

I know that you can send props and states to the element like this:

<Child props={<data>} states={<data>}>

but this doesn't solve the issue with the missing membervariables and in my opinion it isn't a smooth solution.

My attempt so far is (this is just a mockup):

class Parent extends React.Component<any,any> {
  private firstContainer:any;
  private secondContainer:any;
  private currentContainer:any;
  constructor(props:any) {
        super(props);
        this.firstContainer = <Child>;
        this.secondContainer = <Child>;
    }
    public render() {
        return (
            <div>
                {this.currentContainer}
            </div>
        );
    }
    public switchContainer() {
        if(this.currentContainer === this.firstContainer) {
            this.currentContainer = this.secondContainer;
        }
        else {
            this.currentContainer = this.firstContainer;
        }
        this.forceUpdate();
    }
}


class Child extends React.Component<any,any> {
    private anyValue:string;
    constructor(props) {
        this.change = this.change.bind(this);
    }
    public render() {
        return (
            <input onChange={this.change} value={this.anyValue}/>
        );
    }
    private change(e:any) {
        this.anyValue = e.target.value;
    }
}
marius
  • 1,118
  • 1
  • 18
  • 38

1 Answers1

0

You can try maintaining a state and update children in render instead of saving child as firstContainer and secondContainer

class Parent extends React.Component<any, any> {
    constructor(props) {
        super(props);
        this.state = {
            firstChild: true
        };
    }

    public render() {
        const { firstChild } = this.state;
        <div>
            <Child1 show={firstChild}/>
            <Child2 show={!firstChild} />
        </div>
    }

    public switchContainer() {
        this.setState(({ firstChild }) => ({ firstChild: !firstChild }));
    };
}

And in child component, handle show to showContent otherwise render null. If you want to retain state, you should not unmount the component.

Ravi Theja
  • 3,371
  • 1
  • 22
  • 34
  • Thanks for the quick answer, unfortunately this is not possible since the children can be added "on-the-fly" and are not known from the beginning. So the parent-component would always have to rerender the children, once a new child is appended. In your example, whenever "firstChild" changes, the child would rerender, so the member-variable "anyValue" again gets lost. – marius Jul 25 '18 at 11:44
  • 1
    You can store the any value as state in parent component. – Ravi Theja Jul 25 '18 at 11:55