2

I have a React JS app with a simple hierarchy: ContainingBox wraps two InfoBox components. in this example, I simply want to tell the ContainingBox component 1) that something has been clicked, and 2) which InfoBox (by label name) has been clicked?

Here is some basic code that works in my browser to get this question up & running. All it does it console.log when you click onto one of the InfoBox elements on the page.

Essentially, what I am trying to achieve is that I want the ContainingBox to change state (specifically, border color as rendered) when one of the child InfoBox elements is clicked.

I'm not sure what the right direction here is.

I built this app with React 16.10.2, but I would be happy to read answers pointing me towards the latest 'React way' of thinking.

import React from 'react';

import styled from 'styled-components'
import './App.css';


const StyledInfoBox = styled.div`
  width: 100px;
  border: solid 1px green;
  padding: 10px;
  cursor: pointer;
`


class InfoBox extends React.Component {
  constructor({blurb}) {
    super()
    this.state = {
      label: (blurb ?  blurb.label : ""),
    }
    this.selectBox = this.selectBox.bind(this);
  }

  selectBox(e) {
    e.preventDefault()
    console.log("selectBox")

    // how do I tell the ContainingBox component 1) that something has been clicked,
    // and 2) which InfoBox (by label name) has been clicked?
  }

  render() {
    const {label} = this.state
    return (
      <StyledInfoBox onClick={this.selectBox} >
        {label}
      </StyledInfoBox>
    )
  }
}

class ContainingBox extends React.Component {
  render() {
    return (
      <div>
        <InfoBox key={1} blurb={{label: "Aenean malesuada lorem"}} />
        <InfoBox key={2} blurb={{label: "Lorem Ipsum dor ameet"}} />
      </div>
    )
  }
}

function App() {
  return (
    <div className="App">
      <ContainingBox />
    </div>
  )
}

export default App;
halfer
  • 19,824
  • 17
  • 99
  • 186
Jason FB
  • 4,752
  • 3
  • 38
  • 69

1 Answers1

4

You pass a callback from the parent component to child component via the props.

class App extends Component {
  constructor() {
    super();
    this.state = {
      name: 'React'
    };
  }

  changeNameTo = (newName) => this.setState({name: newName})

  render() {
    return (
      <div>
      <h1>{this.state.name}</h1>
        <p>
          <Child callbackExample={this.changeNameTo} />
        </p>
      </div>
    );
  }
}

Then you have your Child component.

class Child extends Component {
    render() {
      return(
        <div>
        <button onClick={() => this.props.callbackExample("Doggos")}>
        Click me
        </button>
      </div>)
    }
}

When you click the button, the callback is invoked setting the state of the parent, which is then reflected when the parent re-renders.

Paul McLoughlin
  • 2,279
  • 2
  • 18
  • 24
  • is this a good example? https://reactjs.org/docs/faq-functions.html#how-do-i-pass-a-parameter-to-an-event-handler-or-callback – Jason FB Oct 16 '19 at 15:43
  • 1
    No, that example is not useful for your problem. You should use (and accept) @Paul McLoughlin answer. – MarcoS Oct 16 '19 at 15:50
  • I am trying to implement this based on the link provided. However, StackOverflow's guidelines say that answers should be complete, without relying on external links, and provide complete examples that clearly satisfy the question. "pass a callback from the parent component to child component via the props" is a general concept. Without implementation details or code examples, this answer may be correct but it does not meet SO's stringent requirements for an proper answer. – Jason FB Oct 17 '19 at 01:29
  • @JasonFB I've updated my answer to include the code sample and removed the link, I hope this helps. – Paul McLoughlin Oct 17 '19 at 08:25
  • yes thank you. I got this 90% working but am stuck on something tangential. I will accept this answer and post a new SO post for the follow-up – Jason FB Oct 18 '19 at 18:11
  • follow-up question, including my refactored implementation based on above pattern, here: https://stackoverflow.com/questions/58456291/in-react-how-do-a-pass-a-parameter-from-a-child-component-up-to-a-parent-compon – Jason FB Oct 18 '19 at 18:22