将计数器组件值传递给它的父组件

Pass counter component value to it's parent component

我有一个简单的计数器子组件。

import React, {useState} from 'react'
import classes from './counter.module.css'

const Counter = (props) => {

    const [number, setNumber] = useState(0);

    const decrementHandler = () => {
        setNumber((prevState) => {
            if(prevState === 0) {
                return 0
            }
            return prevState - 1;
        })
        props.onCounterChange(number);
        
    }

    

    const incrementHandler = () => {
        setNumber((prevState) => {
            return prevState + 1;
        })
        props.onCounterChange(number);
    }



    
    return (
        <>
            <div className={`${classes['counter-wrap']}`}>
                <button className={`${classes['counter-button']} ${classes['decrement']}`} onClick={decrementHandler}>-</button>
                <span className={classes['number']}>{number}</span>
                <button className={`${classes['counter-button']} ${classes['increment']}`} onClick={incrementHandler}>+</button>
            </div>
        </>
    );
    
});

export default Counter;

我想使用 props.onCounterChange() 函数将计数器值 number 传递给父组件。 由于 State 是异步的,我没有收到父级的最新状态值。 如何在状态更改后立即将计数器值传递给 父组件

与 类 不同,React 在 setter 上没有回调作为第二个参数。所以你可以在 setter 回调中调用处理程序,尽管从技术上讲状态还没有改变:

const decrementHandler = () => {
  setNumber((prevState) => {
    if (prevState === 0) {
      return 0
    }
    props.onCounterChange(prevState - 1);
    return prevState - 1;
  })
}

const incrementHandler = () => {
  setNumber((prevState) => {
    props.onCounterChange(prevState + 1);
    return prevState + 1;
  })
}

或者您可以在使用 useEffect 更改状态后调用它,请注意,当组件也使用 0 初始化时将调用它:

useEffect(() => {
  props.onCounterChange(number);
}, [number])

注意不要得到过时的引用,但要确保 onCounterChange 也是常量 (useCallback):

useEffect(() => {
  props.onCounterChange(number);
}, [props.onCounterChange, number])

或者通过隧道传入回调,丑陋但不依赖于用户创建对 onCounterChange 的常量引用(箭头函数每次都是新的):

const onCounterChangeRef = useRef(props.onCounterChange);
onCounterChangeRef.current = props.onCounterChange

useEffect(() => {
  onCounterChangeRef.current(number);
}, [number])