Если я правильно понимаю ваш вопрос, вы хотели бы знать, как добиться того же поведения, которое обеспечивает обратный вызов setState
на основе классов, но с использованием функциональных компонентов.
Мышление в функциональных компонентах - это другоеигра в мяч, а не мышление в компонентах, основанных на классах. Проще всего сказать, что компоненты, основанные на классах, являются более императивными, а хуки / функциональные компоненты - более декларативными.
Для ловушки useEffect
требуется массив зависимостей (часть в конце }, [clicks])
является массивом зависимостей) - каждый раз, когда переменная, включенная в массив зависимостей, изменяется,useEffect
метод запущен.
Это означает, что вы можете использовать useEffect
аналогично обратному вызову setState
. Хуки позволяют вам сосредоточиться и иметь детальный контроль надочень специфические части вашего состояния.
Этот является хорошим потоком для проверки - и, более конкретно, хорошим объяснением различия между основанным на классе (setState
) и основанным на хуках(useState
) парадигмы.
В следующем примере показано, как добиться чего-то похожего на поведение «обратного вызова», но с использованием хуков / функциональных компонентов.
const { render } = ReactDOM;
const { Component, useState, useEffect } = React;
/**
* Class based with setState
*/
class MyClass extends Component {
state = {
clicks: 0,
message: ""
}
checkClicks = () => {
let m = this.state.clicks >= 5 ? "Button has been clicked at least 5 times!" : "";
this.setState({ message: m });
}
handleIncrease = event => {
this.setState({
clicks: this.state.clicks + 1
}, () => this.checkClicks());
}
handleDecrease = event => {
this.setState({
clicks: this.state.clicks - 1
}, () => this.checkClicks());
}
render() {
const { clicks, message } = this.state;
return(
<div>
<h3>MyClass</h3>
<p>Click 'Increase' 5 times</p>
<button onClick={this.handleIncrease}>Increase</button>
<button onClick={this.handleDecrease}>Decrease</button>
<p><b><i>MyClass clicks:</i></b> {clicks}</p>
<p>{message}</p>
</div>
);
}
}
/**
* Function based with useState and useEffect
*/
function MyFunction() {
const [clicks, setClicks] = useState(0);
const [message, setMessage] = useState("");
useEffect(() => {
let m = clicks >= 5 ? "Button has been clicked at least 5 times!" : "";
setMessage(m);
}, [clicks]);
const handleIncrease = event => setClicks(clicks + 1);
const handleDecrease = event => setClicks(clicks - 1);
return(
<div>
<h3>MyFunction</h3>
<p>Click 'Increase' 5 times</p>
<button onClick={handleIncrease}>Increase</button>
<button onClick={handleDecrease}>Decrease</button>
<p><b><i>MyFunction clicks:</i></b> {clicks}</p>
<p>{message}</p>
</div>
);
}
function App() {
return(
<div>
<MyClass />
<hr />
<MyFunction />
</div>
);
}
render(<App />, document.body);
p {
margin: 1px;
}
h3 {
margin-bottom: 2px;
}
h3 {
margin-top: 1px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js"></script>