Стиль кода useState

С помощью useState происходит рендринг чтобы поменялось значение на странице, везде вижу, что используют только тип данных const и меняют значение вот такsetCount(count+1); Можно ли использовать, let при создание useState и менять так count+=1;setCount(count+1); ? или так не рекомендовано?

  let [count,setCount]=useState(0)
  const [count,setCount]=useState(0)

Ответы (2 шт):

Автор решения: SwaD

Немного сумбурно получилось...

Можно использовать конструкцию

let [a, setAa] = React.useState(0);
a++;

Нам это никто не запрещает, особенно, что мы можем это сделать. Только это не приведет к изменению самого состояния.
Да, можно сделать так:

let [a, setAa] = React.useState(0);
a++;
setA(a);

НО! Это не рекомендовано и даже не правильно, однако, да, можно так сделать :)

const используют для того, что бы уберечь себя от случайного изменения данных.

Однако есть Объекты. React это все тот же javaScript и useState возвращает не склонированный объект, а ссылку на него, поэтому можно "неумышленно" изменить состоние компонента.

const [obj, setObj] = React.useState({ a: 5 });
obj.c = 'new';

Теперь и в компоненте obj и в состоянии одни и те же данные, однако, такое изменение не вызовет ререндер компонента, так как передается ссылка на тот же объект и при сравнении, старые данные и новые будут равны. Такого поведения стоит избегать.

const [obj, setObj] = React.useState({ a: 5 });
obj.c = 'new';
setObj(obj); // не вызовет повтоный рендеринг

Для возможности повторного рендера при работе с объектами, лучше использовать spread оператор

const [obj, setObj] = React.useState({ a: 5 });
obj.c = 'new';
setObj({ ...obj }); // вызовет повтоный рендеринг

Ниже полный код с приведенными выше примерами:

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);

const ObjChange = () => {
  const [obj, setObj] = React.useState({ a: 5 });
  const [arr, setArr] = React.useState([1, 2]);
  
  const changeObj = () => {
    obj.b = obj.b ? ++obj.b : 1;
    setObj(obj);
    arr.push(3);
    setArr(arr);
  };

  const changeObjUpd = () => {
    obj.b = obj.b ? ++obj.b : 1;
    setObj({ ...obj });
    arr.push(3);
    setArr([...arr]);
  };

  return (
    <div>
      Текущее состояние объекта: {obj.a} {obj.b}
      <br />
      Текущее состояние массива: {arr.map((i) => i)}
      <br />
      <button onClick={() => changeObj()}>Поменять данные</button>
      <button onClick={() => changeObjUpd()}>Поменять данные и обновить</button>
    </div>
  );
};

function App() {
  let [a, Sa] = React.useState(0);
  console.log("Begin", a);
  a++;
  a++;
  a++;
  a++;
  console.log("End", a);
  return (
    <div className="App">
      <h1>
        a: {a} 
        <button
          onClick={() =>
            Sa((e) => {
              console.log("Current", e);
              return e + 10;
            })
          }
        >
          Прибавить 10
        </button>
      </h1>
      <hr />
      <ObjChange />
    </div>
  );
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>

<div id='root'></div>

→ Ссылка
Автор решения: Сергей Мельниченко

В дополнение к предыдущему ответу.

setState(count + 1) - так не рекомендуется делать.

setState((currentCount) => currentCount + 1) используйте коллбэк, чтобы избежать нечто похожего на гонку данных, в том случае, если событие, вызывающее setState(), будет слишком быстро срабатывать (к примеру, очень быстро кликать на кнопку, которая меняет счетчик).

→ Ссылка