0

I'm trying to update child component which has a prop with parent state. While changing state of parent with setState() to my knowlage chlid should rerender. But when child is in an array rerender does not occure. How can i fix that? Thanks in advance.

My child class:

class Child extends Component {
  render() {
    return(
      <Text>{this.props.state.isActive.toString()}</Text>
    )
  }
}

My parent class:

class Parent extends Component {

  state = {
    isActive: false
  }

  children = []


  constructor(props) {
    super(props)
    this.createChildren()
    this.changeState()
  }

  changeState() {
    this.change = setInterval(() => {
      if(this.state.isActive){
        this.setState({isActive: false})
      } else {
        this.setState({isActive: true})
      }
    }, 1000)
  }


  componentWillUnmount() {
    clearInterval(this.change)
  }

  createChildren() {
    for(let i=0; i<5; i++) {
      this.children.push(<Child key={i} state={this.state}/>)
    }
  }

  render() {
    return(
      <View>
        {this.children}
      </View>
    )
  }
}

My app function:

export default function App() {
  return (
    <View style={style.conteiner}>
      <Parent/>
    </View>
  );
} 
HavilMal
  • 5
  • 2
  • Based on your parent -> child component setup, I think this SO post may help you: https://stackoverflow.com/a/41233828/1188197 – EspressoBeans Jun 15 '21 at 15:24

2 Answers2

1

React elements should always be created during render. Do not store them in a property or in component state:

  renderChildren = () => {
    children = [];

    for(let i=0; i<5; i++) {
      children.push(<Child key={i} state={this.state}/>)
    }

    return children;
  }

  render() {
    return(
      <View>
        {this.renderChildren()}
      </View>
    )
  }

You are basically rendering always the same elements that you created once in the constructor (which also is an anti-pattern).

trixn
  • 15,761
  • 2
  • 38
  • 55
0

What you are doing is not going to work, since you are pushing <Child/> components to a class attribute which is only called inside the constructor; so these <Child/> components will refer to only initial state, not the now updated state. You will have to call a getChildren() function inside the render. I've fixed the issue in react, you can translate to react native replacing the divs with Views, see codesandbox : https://codesandbox.io/s/pedantic-jackson-wgtnh?file=/src/App.js

Anuja
  • 908
  • 6
  • 11