Reputation: 85
I've started splitting some code into presentational/container
components and I'd like to call a function in the child/presentational
component and pass both the event and some sort of prop back to the parent.
Parent:
class Parent extends Component{
constructor(props) {
super(props);
this.state = {}
this.reroll = this.reroll.bind(this);
}
test(key, e){
console.log(key, e)
}
render() {
return <Child test={()=>this.test} />
}
}
Child:
var Child = () => {
return (
<select onChange={props.test('test-key')}>
<option value='1'> Option 1 </option>
//etc...
</select>
)
}
Normally, when I had my code all in one place I would write the onChange function like this.
<select onChange={props.test.bind(this, 'test-key')}>
But binding this in the child causes it to no longer function. No other props passed to this function get returned to the parent. Is there any way that I can write this such that I can get back 'test-key'?
Upvotes: 7
Views: 27971
Reputation: 814
Anyone coming here trying to find same thing for functional component. I have an example here. Parent component example:
<SaveButton
newsArticleId="someId"
onClickCallback={handleSaveNote}
/>
const handleSaveNote = (e, articleId) => {
const event = e || window.event;
event.preventDefault();
setArticleId(articleId);
....code removed
};
Child component example:
const SaveButton = ({ newsArticleId, onClickCallback }) => {
return (
<button
id={newsArticleId}
className='btn btn-sm btn-primary'
type='button'
data-toggle='dropdown'
aria-haspopup='true'
aria-expanded='false'
onClick={(e) => onClickCallback(e, newsArticleId)}
>
Save
</button>
);
};
Upvotes: 6
Reputation: 281606
First: You should avoid binding the functions as much as possible in the render as it causes a new function to be created each time render is called. You could easily avoid it in your case like
define the test function using arrow function
test(key, e){
console.log(key, e)
}
and then use it in the parent like
<Child test={this.test} />
now in the child component
test = (e) => {
this.props.test('test-key', e)
}
<select onChange={this.test}>
Upvotes: 12
Reputation: 15292
You need to put function call inside callback of onChange
event.
<select onChange={()=>props.test('test-key')}>
In this way you can also pass event
object too.
<select onChange={(event)=>props.test(event,'test-key')}>
Upvotes: 8