In React JS, I am having trouble passing a value from a child component up to the parent component
this question is a follow-up to previous question In React JS, how do I tell a parent component that something has happened in the child?
here is the code example I am working with...
I have one problems and two questions:
1) although 'label' is in scope (and I can see it has a value in the debugger) in the render method of InfoBox
, when it gets passed up to ContainingBox's boxChosen
method, it always comes up 'undefined'. what am I doing wrong here?
2) Is there any way to reduce the repetition (DRY this up) when using JSX to construct the InfoBox. In particular, it bothers me that selectBox={this.boxChosen}
is repeated for each instance of InfoBox in the JSX
3) is there any common pattern or accepted practice for the naming of the methods in children or parents? In particular, you'll see that this code lets me define one method called selectBox
in the child and another one called boxChosen
in the parent. This seems arbitrary to me, as I just picked two separate names that didn't collide so as to make it more understandable. But it strikes me as in a larger app you'd want a consistent function naming pattern to identify which methods were 'pass through' methods (in this case, selectBox
) simply passing stuff back up to parents. I don't know; just a thought about whether or not there's a naming convention.
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 : ""),
}
}
render() {
const {label} = this.state
return (
<StyledInfoBox onClick={() => {
const {label} = this.state
// although 'label' is in scope here, it seems to not be
// correctly passed up to selectBox
this.props.selectBox(this.label)
}
} >
{label}
</StyledInfoBox>
)
}
}
class ContainingBox extends React.Component {
boxChosen =(label) => {
// for some reason label comes out as undefined here
console.log("boxChosen.......", label)
}
render() {
return (
<div>
<InfoBox key={1} blurb={{label: "Aenean malesuada lorem"}} selectBox={this.boxChosen} />
<InfoBox key={2} blurb={{label: "Lorem Ipsum dor ameet"}} selectBox={this.boxChosen} />
</div>
)
}
}
function App() {
return (
<div className="App">
<ContainingBox />
</div>
)
}
export default App;