Reputation: 1097
I found the following code in this post.(sandbox) I am not sure why these buttons behave differently.
One possible explanation is: Because Button's render method is not invoked for updating, the first button's click handler remains the same. However, this.props of the Button instance has changed to include the new onClick prop. In other words,if the props of a component element is changed, nextProps will finally become this.props even when shouldComponentUpdate returns false.
const submit = val => alert(val);
class App extends React.Component {
state = { val: "one" }
componentDidMount() {
this.setState({ val: "two" })
}
render() {
return <Form value={this.state.val} />
}
}
const Form = props => (
<Button
onClick={() => {
submit(props.value)
}}
/>
)
class Button extends React.Component {
shouldComponentUpdate() {
// lets pretend like we compared everything but functions
return false
}
handleClick = () => this.props.onClick()
render() {
return (
<div>
<button onClick={this.props.onClick}>This one is stale</button>
<button onClick={() => this.props.onClick()}>This one works</button>
<button onClick={this.handleClick}>This one works too</button>
</div>
)
}
}
Upvotes: 0
Views: 7046
Reputation: 2382
Your explanation is correct on that when ShouldComponentUpdate()
returns false
, the Button
component does not re-render on props change.
In the first <button>
element, the onClick
event is this.props.OnClick
which is actually the function () => { submit("one"); }
at the moment of the initial rendering. "one"
is here because at this particular time point in the React lifecycle, Form
's props.value
evaluates to "one"
. Note that the function gets executed has nothing to do with Button
's props
.
In the second <button>
element, however, the onClick
event is () => this.props.onClick()
. Regardless whether the Button
component gets re-rendered, it is always the this.props.onClick()
that get executed, where this.props
changes when the parent components get state/props updates.
In the case of ShouldComponentUpdate()
returning true
, Button
component will re-render on props updates. The first button's onClick
event becomes a new function () => { submit("two"); }
on the re-render triggered by the App
component's state change. The two button elements' onClick
event functions are never the same function, although they appear to produce the same result.
Upvotes: 1
Reputation: 7492
<button onClick={this.props.onClick}>
Will call your onClick function and send an event
object as its first parameter. This is the equivalent of doing this :
<button onClick={event => { this.props.onClick(event) }}>
<button onClick={() => this.props.onClick()}>
Will set what your onClick function returns as the onClick function... It is the short syntax of the following code :
<button onClick={() => { return this.props.onClick() }}>
What you may be looking for is this : <button onClick={() => { this.props.onClick() }}>
In this case, clicking will simply call your function without sending any arguments
I suggest reading this documentation to know more about arrow/anonymous functions and their syntax
Upvotes: 0