0

I am trying to pass the data from nested child to it's parent component I am fairly new React developer. I have created a multilevel drop-down component and i am passing the data from it's parent.Now I need to send the selected data back to it's parent component from child component.I got stuck here. Or it's just not they way to create dynamic multilevel drop-down.

class Product extends React.Component {
  constructor(props) {
    super(props);
    this.toggleHidden = this.toggleHidden.bind(this);
    this.state = {
      isHovered: false,
    }
  }

  toggleHidden () {
    this.setState({
      isHovered: !this.state.isHovered
    })
  }
  
  render() {
    const styles = {
      'backgroundColor': this.props.lightColor,
    }
    if (this.state.isHovered) {
      styles['backgroundColor'] = "#000000";
      styles['color'] = '#28d4ee';
    }

    return (
      <div className='singleProduct'
           onMouseEnter={this.toggleHidden}
           onMouseLeave={this.toggleHidden}
           style={styles}
           onClick={() => this.props.handleClick(this.props.id, this.props.name)}>
           
           {this.props.name}
      </div>
    )
  }
}

class ProductGroup extends React.Component {
  constructor(props) {
    super(props);
    this.toggleHidden = this.toggleHidden.bind(this);
    this.handleClick = this.handleClick.bind(this);
   
    this.state = {
      isVisible: false,
      id: "",
    }
  }


  toggleHidden () {
    this.setState({
      isVisible: !this.state.isVisible
    })
  }
  //I need to send the ID to the parent Component
  async handleClick(id, name) {
    await this.setState({
      id,
      name
     });
     await this.props.replace(name);

  }

  render() {
    const BackgroundColor = "#000000";
    // Only make bg color if on hover
    const bgStyle = {
    }
    if (this.state.isVisible) {
      bgStyle['backgroundColor'] = BackgroundColor;
      bgStyle['borderLeft'] = '5px solid || {this.props.color}';
      bgStyle['color'] = "#28d4ee";
    }
    return (
      <div className='productGroup'
           onMouseEnter={this.toggleHidden}
           onMouseLeave={this.toggleHidden}
           style={bgStyle}>
        <i className={this.props.name}></i>
        {this.props.name}
        <span style={bgStyle} class="glyphicon glyphicon-triangle-right pull-right"></span>
        
        <div className={`productSet ${this.state.isVisible ? 'visible': ''}`}>
          {this.props.product.map(product => <Product
              key={product.id}
              id={product.id}
              name={product.name}
              lightColor={BackgroundColor}
              color={this.props.color}
              handleClick ={this.handleClick}
            />)}
        </div>
      </div>
    )
  }
}

class ProductGroupSelector extends React.Component {
  constructor(props) {
    super(props);
    this.toggleHidden = this.toggleHidden.bind(this);
    this.state = {
      isVisible: false,
      buttonText: "CHOOSE A SPORT"
      
    }
    console.log(props, "propssssss")
  }

  toggleHidden () {
    this.setState({
      isVisible: !this.state.isVisible
    })
  }

  changeContent = name => {
    this.setState({
      buttonText: name
    });
    console.log(name, "name")
  };


  render() {
    const productGroups = this.props.productGroups;
    return (
   
      <div className='dropdown' onClick={this.toggleHidden}>
  
        <div className='topButton'>
            {this.state.buttonText}  
            <span class="glyphicon glyphicon-triangle-bottom pull-right"></span>

        </div>
        <div className={`dropDownM ${this.state.isVisible ? 'visible': ''}`}>
          {productGroups.map(group => <ProductGroup replace = {this.changeContent} key={group.id} name={group.name} color="#123eee" product={group.products} />)}
        </div>
      </div>
    )
  }
}


class Dropdown extends React.Component {
  render() {
    const availableModules = this.props.availableModules;
    return (
      <div>
        <ProductGroupSelector productGroups={availableModules} />
      </div>
    )
  }
}


These all the components are in single file, I have a component where i am calling Drop-down component and sharing data from.

class ParentComponent extends React.Component {
  render() {
    const availableModules = "data": {
                 "category_products": [{
                    "id": 1,
                    "name": "Indoor",
                    "group": "Activities",
                    "products": [
                        {
                            "id": 2,
                            "name": "Shooting",
                            "category_id": 1
                        },
                        {
                            "id": 3,
                            "name": "Car Sim",
                            "category_id": 1
                        },
                        {
                            "id": 4,
                            "name": "Flight Sim",
                            "category_id": 1
                        }
                   }]
                  }
    return (
      <div>
        <Dropdown productGroups={availableModules} />
      </div>
    )
  }
}

ReactDOM.render(<ParentComponent/>, document.getElementById("root"));
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>
<script type="text/babel">
Gaurav
  • 11
  • 2
  • What is the issue here? Are you not able to get the data in the `ParentComponent`? – SerShubham Jun 05 '19 at 01:47
  • Hi @SerShubham I am setting the state Id on handleClick on ProductGroup component . Now i need to send the data to it parent component.From Child to parent we can send the data using Callback function but how exactly i would do that in nested component. – Gaurav Jun 05 '19 at 01:56
  • Though there are different ways to pass data from child to parent, the standard way is to use Redux. Since you are new to react, its good opportunity to explore one way data flow using Redux. Please check https://redux.js.org/. Other options are https://reactjs.org/docs/render-props.html and https://stackoverflow.com/a/38397755/1897654 – Uday Sravan K Jun 05 '19 at 02:01
  • Even if i use redux it's not solving my issue.In one file i have all the childs I am exporting Dropdown. .export default connect( mapStateToProps, {getSelectedId} )(Dropdown); I can't connect the productGroup component state or i can't export 2 components. – Gaurav Jun 05 '19 at 02:31
  • @UdaySravanK, why would you say that "the standard way is to use Redux"? Most people will actually advise to NOT do that. You shouldn't add a state manager to your project until you really have a complex state management requirement. In fact, you shouldn't add anything to your project until you really need it :) Although you are right when you say that there are many ways to do it (and Redux it is a way to do it, but not the recommended or standard one), the best solution is probably to lift up the state: https://reactjs.org/docs/lifting-state-up.html – Bruno Monteiro Jun 05 '19 at 03:35
  • Possible duplicate of [How to update parent's state in React?](https://stackoverflow.com/questions/35537229/how-to-update-parents-state-in-react) – Bruno Monteiro Jun 05 '19 at 05:07
  • @BrunoMonteiro Agreed. Since, Gaurav is beginner, I just wanted to put him in the direction to understand the state management. Of course Redux is not a standard but I mean one way data flow is standard/ preferred in react. Passing a parent function to child is simplest solution. – Uday Sravan K Jun 05 '19 at 16:27

0 Answers0