Как поменять состояние одного компонента, реагируя на событие в другом в React?

В React, для изменения состояния одного компонента, реагируя на событие в другом компоненте, мы можем использовать концепцию "подъема состояния" или передавать функцию обратного вызова (callback) через пропсы.

1. Подъем состояния (Lifting State Up):
- При использовании этого подхода, мы перемещаем общее состояние, которое оба компонента должны изменять, в их общего родителя.
- Состояние и функция для его обновления передаются в каждый компонент в качестве пропсов.
- Когда происходит событие в одном компоненте, вызывается функция обратного вызова пропса, передавая в нее новое значение состояния.
- Родитель обновляет состояние и передаёт его и функцию обновления в каждый компонент, вызывая повторное рендеринг.

Пример кода:

   import React, { useState } from "react";

   const ParentComponent = () => {
     const [counter, setCounter] = useState(0);

     const handleIncrement = () => {
       setCounter(counter + 1);
     };

     return (
       <div>
         <ChildComponent counter={counter} onIncrement={handleIncrement} />
       </div>
     );
   };

   const ChildComponent = ({ counter, onIncrement }) => {
     return (
       <div>
         <p>Counter value: {counter}</p>
         <button onClick={onIncrement}>Increment</button>
       </div>
     );
   };

2. Callback функции:
- В этом подходе мы передаем функцию обратного вызова из родительского компонента в дочерний компонент через пропсы.
- Когда происходит событие в дочернем компоненте, вызывается переданная функция обратного вызова, передавая в нее новое значение, которое должно быть установлено в состоянии.
- Родительский компонент обновляет свое состояние и вызывает повторное рендеринг.

Пример кода:

   import React, { useState } from "react";

   const ParentComponent = () => {
     const [counter, setCounter] = useState(0);

     const handleIncrement = () => {
       setCounter(counter + 1);
     };

     return (
       <div>
         <ChildComponent onIncrement={handleIncrement} />
         <p>Counter value: {counter}</p>
       </div>
     );
   };

   const ChildComponent = ({ onIncrement }) => {
     const handleClick = () => {
       onIncrement();
     };

     return (
       <div>
         <button onClick={handleClick}>Increment</button>
       </div>
     );
   };

Оба подхода имеют свои преимущества и могут использоваться в зависимости от ситуации. Подъем состояния полезен, когда у нас есть несколько компонентов, которые должны иметь доступ к общему состоянию или когда компоненты находятся на разных уровнях иерархии. Использование callback функций удобно, когда компоненты являются непосредственными соседями и мы хотим передать только функцию обратного вызова без необходимости передавать все общие состояния.