4

I try to pass argument from child component to parent. P.S. Snippet below doesn't work if somebody fix this, it would be really great.

class Parent extends React.Component {

  suggestionClick(id) {
    console.log(this.props, id); // {props Object} , undefined
  }

  render(){
    return (
      <ChildComponent click={this.suggestionClick.bind(this)} />
    );
  }
}


const ChildComponent = ({ click }) => (
  <SubChildComponent id="1" click={() => click()} />
);

const SubChildComponent = ({ click, id }) => (
  <div className="subsubcomponent" click={() => click(id)} />
);



ReactDOM.render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

1
  • @Chris )) old logo of vk.com - russian duplicate of fb.com Commented Jan 15, 2018 at 15:05

4 Answers 4

6
  1. Don't use divs to trigger clicks. The right way is using a button for example
  2. The right function handler is onClick not just click

class Parent extends React.Component {

  suggestionClick(id) {
    alert(id);
    console.log(this.props, id); // {props Object} , undefined
  }

  render(){
    return (
      <ChildComponent click={this.suggestionClick.bind(this)} />
    );
  }
}


const ChildComponent = ({ click }) => (
  <SubChildComponent id="1" click={click} />
);

const SubChildComponent = ({ click, id }) => (
  <button className="subsubcomponent" onClick={() => click(id)}>click me</button>
);



ReactDOM.render(
  <Parent />,
  document.getElementById('app')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

Sign up to request clarification or add additional context in comments.

Comments

3

This is because you are not passing the value from ChildComponent to parent component, here:

<SubChildComponent id="1" click={() => click()} />

Use this:

<SubChildComponent id="1" click={(id) => click(id)} />

Or Simply:

<SubChildComponent id="1" click={click} />

Another change is replace click with onClick inside SubChildComponent.

Working Code:

class Parent extends React.Component {

  suggestionClick(id) {
    console.log(this.props, id); // {props Object} , undefined
  }

  render(){
    return (
      <ChildComponent click={this.suggestionClick.bind(this)} />
    );
  }
}


const ChildComponent = ({ click }) => (
  <SubChildComponent id="1" click={(id) => click(id)} />
);

const SubChildComponent = ({ click, id }) => (
  <div className="subsubcomponent" onClick={() => click(id)}>Click</div>
);



ReactDOM.render(
  <Parent />,
  document.body
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

Comments

1

In ChildComponent, just pass the click property directly to the SubChildComponent:

const ChildComponent = ({ click }) => (
  <SubChildComponent id="1" click={click} />
);

Comments

0

You can also use es6 arrow function in your parent component, therefore no need to bind this to this function explicitly.

However when we call this function from child along with id to be passed to it, we bind this for passing the id value. Below is the modified code for reference. Hope this helps.

class Parent extends React.Component {

  // make this function as arrow function
  suggestionClick = (id) => {
    console.log(this.props, id); // {props Object} , id
  }

  render(){
    return (
      <ChildComponent click={this.suggestionClick} />
    );
  }
}


const ChildComponent = (props) => (
  <SubChildComponent id="1" click={props.click} />
);

const SubChildComponent = (props) => (
  <div className="subsubcomponent" onClick={props.click.bind(this, props.id)} />
);



ReactDOM.render(
  <Parent />,
  document.getElementById('app')
);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.