Skip to content

Instantly share code, notes, and snippets.

@ryanflorence
Last active June 26, 2018 13:35
Show Gist options
  • Save ryanflorence/9e40e895750ec93a0fa64e15afef52fc to your computer and use it in GitHub Desktop.
Save ryanflorence/9e40e895750ec93a0fa64e15afef52fc to your computer and use it in GitHub Desktop.
// 1. App will pass a prop to Form
// 2. Form is going to pass a function down to button
// that closes over the prop it got from App
// 3. App is going to setState after mounting and pass
// a *new* prop to Form
// 4. Form passes a new function to Button, closing over
// the new prop
// 5. Button is going to ignore the new function, and fail to
// update the click handler, submitting with stale data
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>
)
}
}
@ackvf
Copy link

ackvf commented Apr 9, 2018

So, the Button props DO change internally (?), but render won't get called, hence we have buttons rendered with old props, where

  1. references an old this.props.onClick function
  2. references a previous version of the arrow function, that itself accesses the current this.props.onClick in time of invocation
  3. Same as 2) except it is a reference to the never changing handleClick

?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment