wake-0
wake-0

Reputation: 3968

ReactJS component state does not change as expected

I created a Container class and an InnerElement class. Where the Container wraps the InnerElements. It is necessary to show just a single InnerElement at a given time.

The problem appears, when I change to another InnerElement. Interestingly when I create a console.log it displays the changed element but it is not rendered. Could someone give me a hint please, thanks in advance!

Container class:

import React from 'react';

export default class Container extends React.Component {

    constructor(props) {
        super(props);

        this.changeElement = this.changeElement.bind(this);

        this.state = {
            currentElement: 0,
        }
    }

    changeElement() {
        const nextElement = this.state.currentElement + 1;
        this.setState({currentElement: nextElement});
    }

    render() {
        const element = this.props.children[this.state.currentElement];
        // In the console log the next (correct) element is shown
        console.log(element);

        return (
            <div>
                {element}
                <button onClick={this.changeElement}>next element</button>
            </div>
        );
    }
}

Here the InnerElement class:

import React from 'react';
export default class InnerElement extends React.Component {

    constructor(props) {
        super(props);

        this.state = {
            name: props.name ? props.name : "test"
        }
    }

    render() {
        return (
            <div>
                {this.state.name}
            </div>
        );
    }
}

And here my Container with InnerElement call:

<Container>
    <InnerElement name="A" />
    <InnerElement name="B" />
    <InnerElement name="C" />
    <InnerElement name="D" />
</Container>

I also discovered, that it works, when I use in the InnerElement this.props.name instead of the state.

Upvotes: 0

Views: 38

Answers (1)

Axnyff
Axnyff

Reputation: 9944

React have trouble determining your children is changing with your setState because you are dynamically modifying the children. To help React do this, you can add a key to your InnerElement:

<Container>
  <InnerElement key="A" name="A" />
  <InnerElement key="B" name="B" />
  <InnerElement key="C" name="C" />
  <InnerElement key="D" name="D" />
</Container>

Upvotes: 1

Related Questions