В вашем текущем примере, где вы устанавливаете состояние по умолчанию { count: 0 }
, вы "безопасно" выполнять setState({ count: this.state.count + 1 })
, потому что при первом обновлении вашего состояния 0 + 1
даст действительный результат.
class App extends React.Component {
state = { count: 0 }
render() {
return (
<div>
<p>You clicked {this.state.count} times</p>
<button
onClick={() => this.setState({ count: this.state.count + 1 })}
>
Click me!
</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById("app")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Однако давайте предположим, что ваше начальное значение для некоторого фрагмента state
не 0
, поэтому вызов this.state.count + 1
может привести к неверному результату. Это то место, где вы бы достигли версии callback
, потому что:
вы не уверены, каково захваченное значение состояния.
class App extends React.Component {
state = { count: null }
render() {
const handleClick = () => {
this.setState((prevState) => {
// count is initially `null`, so
// `null + 1` could yield an undesired result
if (!Number.isInteger(prevState.count)) {
return { count: 1 }
}
return { count: prevState.count + 1 }
})
}
return (
<div>
<p>You clicked {this.state.count} times</p>
<button onClick={handleClick}>
Click me!
</button>
</div>
)
}
}
ReactDOM.render(
<App />,
document.getElementById("app")
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Это всего лишь пример, но вы поняли.
Ваш PR, скорее всего, был отклонен, потому что пример в Документы верны, если они используются в том же контексте, где «безопасно» обновлять состояние, выполняя this.setState({ count: this.state.count + 1 })
.
Вот документация:
Оба способа обновления state
являются правильными и должны использоваться при необходимости. Как вы можете видеть во втором примере, «опция обратного вызова» была бы лучшим решением, если вы хотите выполнить некоторые проверки перед обновлением state
.
Тем не менее пример в документации правильный и не принесет никаких преимуществ, если бы вместо этого использовался «параметр обратного вызова».