REACT значение на странице не совпадает со значением в консоли

Рейтинг: 0Ответов: 1Опубликовано: 02.03.2023

есть компонент Counter, который по клику прибавляет и убавляет значение count. count это state, который идет выше в родительский компонент и вызывает функцию onCountChange в родительском компоненте. (который считает сумму, еще не знаю как, но вопрос не в этом).

Проблема: когда по клику вызывается onCountChange, значение count не совпадает с тем что отображается на странице.

Например: Значение - 5, нажимаю "+", отображается на странице - 6, а в логе функции onCountChange - 5.

Примерно я понимаю что это из-за того что реакт сохроняет state асинхронно и я пытался обвернуть setState в функцию (в функциях increment() и decrement(), отсюда https://ru.reactjs.org/docs/faq-state.html). Типо такого:

setCount((count) => count + 1)

Но это не сработало.

Пытался одновременно с onClick передавать state в функцию выше, так

onClick={()=>{increment(); onCountChange(count)}}

Но тоже не удачно. Еще одна идея использовать Promise, но это последний вариант. Подскажите плз.

import React, {useState} from 'react';
import styles from './Counter.module.scss';

const Counter = ({title, value, onCountChange}) => {
  
  const MIN = 0;
  const MAX = 99;

  (function valueValidation(){
      value < MIN ? value = MIN : value
      value > MAX ? value = MAX : value
    })()

  const [count, setCount] = useState(value);

  function increment() {
    count < MAX && setCount(count + 1)
    console.log(count);
    onCountChange(count)
  }

  function decrement() {
    count > MIN && setCount(count - 1)
    console.log(count);
    onCountChange(count)
  }
  return (
    <div className={styles['counter']}>
      <p className={styles['counter__title']}>{title}</p>
      <div className={styles['counter__calculate']}>
        <button
          className={styles['counter__btn']}
          onClick={decrement}>
          -
        </button>
        <h6 className={styles['counter__count']} >{count}</h6>
        <button
          className={styles['counter__btn']}
          onClick={increment}>
          +
        </button>
      </div>
    </div>
  )
}

export default Counter;

Родительский компонент:

const onCountChange = ((res) => {
          console.log(res);
});

<Counter key={item.id} title={item.title} value={item.value} onCountChange={onCountChange} />

Ответы

▲ 1Принят

Чтобы получить актуальное значение count необходимо использовать useEffect.

import React, {useState, useEffect} from 'react';
import styles from './Counter.module.scss';

const Counter = ({title, value, onCountChange}) => {
  
  const MIN = 0;
  const MAX = 99;

  (function valueValidation(){
      value < MIN ? value = MIN : value
      value > MAX ? value = MAX : value
    })()

  const [count, setCount] = useState(value);
  useEffect(() => onCountChange(count), [count]);

  function increment() {
    count < MAX && setCount(count + 1)
    console.log(count);
  }

  function decrement() {
    count > MIN && setCount(count - 1)
    console.log(count);
  }
  return (
    <div className={styles['counter']}>
      <p className={styles['counter__title']}>{title}</p>
      <div className={styles['counter__calculate']}>
        <button
          className={styles['counter__btn']}
          onClick={decrement}>
          -
        </button>
        <h6 className={styles['counter__count']} >{count}</h6>
        <button
          className={styles['counter__btn']}
          onClick={increment}>
          +
        </button>
      </div>
    </div>
  )
}

export default Counter;