Search code examples
reactjshandler

Unable to update props in child component


This is my parent Component having state ( value and item ). I am trying to pass value state as a props to child component. The code executed in render method is Performing toggle when i click on button. But when i call the list function inside componentDidMount, Toggle is not working but click event is performed.

import React, { Component } from 'react'
import Card from './Components/Card/Card'

export class App extends Component {
  
  state = {
    values : new Array(4).fill(false),
    item : [],
  }

  toggleHandler = (index) => {
    console.log("CLICKED");
    let stateObject = this.state.values;
    stateObject.splice(index,1,!this.state.values[index]);
    this.setState({ values: stateObject });
  }

  list = () => {
    const listItem = this.state.values.map((data, index) => {
      return <Card key = {index} 
        show = {this.state.values[index]} 
        toggleHandler = {() => this.toggleHandler(index)} />
    })
    this.setState({ item : listItem  });
  }

  componentDidMount(){
    // if this is not executed as the JSX is render method is executed everything is working fine. as props are getting update in child component.
    this.list();
  }

  render() {
    
    return (
      <div>
      {/* {this.state.values.map((data, index) => {
        return <Card key = {index} 
          show = {this.state.values[index]} 
          toggleHandler = {() => this.toggleHandler(index)} />
      })
      } */}

      {this.state.item}

      </div>
    )
  }
}

export default App

This is my child Component where the state is passed as props

import React from 'react'

const Card = (props) => {
    return (
        <div>
            <section>
                <h1>Name : John Doe</h1>
                <h3>Age : 20 </h3>
            </section>
            
            {props.show ?
                <section>Skills : good at nothing</section> : null
            }
            <button onClick={props.toggleHandler} >Toggle</button>
        </div>
    )
}

export default Card

I know the componentDidMount is executed only once. but how to make it work except writing the JSX directly inside render method


Solution

  • Value should be mapped inside render() of the class component in order to work

    like this:

     render() {
        const { values } = this.state;
        return (
          <div>
            {values.map((data, index) => {
              return (
                <Card
                  key={index}
                  show={values[index]}
                  toggleHandler={() => this.toggleHandler(index)}
                />
              );
            })}
          </div>
        );
      }
    

    check sandbox for demo

    https://codesandbox.io/s/stupefied-spence-67p4f?file=/src/App.js