繁体   English   中英

对 props 块组件中的原生回调 function 做出反应以重新渲染

[英]react native callback function in props blocks component to rerender

我有这个反应原生组件,它创建一个带有增加和减少按钮的通用数字输入。

带按钮的数字输入

export default function NumberInput({quantity = 0, onquantityChange}) {
  const [number, SetNumber] = useState(quantity);

  function handleIncrease() {
    SetNumber(number + 1);
    onquantityChange(quantity + 1);
  }


  function handleDecrease() {
    if (number > 0) {
      SetNumber(number - 1);
      onquantityChange(quantity - 1);
    }
  }

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={handleDecrease} activeOpacity={0.6}>
        <Icon name="minus" size={20} color={colors.white} style={styles.icon} />
      </TouchableOpacity>
      <AppText style={styles.text}>{number}</AppText>
      <TouchableOpacity onPress={handleIncrease} activeOpacity={0.6}>
        <Icon name="plus" size={20} color={colors.white} style={styles.icon} />
      </TouchableOpacity>
    </View>
  );
}

当我按下 + 或 - 按钮时, onquantityChange function 使数字的增加和减少变慢,如果我评论它,它将几乎实时重新呈现。 onquantityChange function 在父函数中做了一些繁重的工作)。

我也用过这个版本,稍微好一点但没有太大变化:

  const [number, SetNumber] = useState(quantity);

  function handleIncrease() {
    SetNumber(number + 1);
  }

  useEffect(() => {
    onquantityChange(number);
  }, [number]);

  function handleDecrease() {
    if (number > 0) {
      SetNumber(number - 1);
    }
  }

我该怎么做才能使数字和 UI 重新呈现并且不等待onquantityChange

通过在 useEffect 中使用setTimeout ,我们可以使onquantityChange不会在每次number更改时运行,setTimeout 也会在“堆栈为空时”运行它。

在主线程上的堆栈为空之前,您传递给这些函数的回调无法运行。

引用MDN

所以我把我的 function 组件改成了这个。

//this have to be outside of the function component.
let changeTimeout;

export default function NumberInput({value = 0, onChange}) {
  const [number, SetNumber] = useState(value);

  function handleIncrease() {
    SetNumber(number + 1);
  }

  //use setTimeout to delay onChange to a time when main thread is available 
  useEffect(() => {
    changeTimeout && clearTimeout(changeTimeout);
    changeTimeout = setTimeout(() => {
      onChange(number);
    }, 500);
  }, [number]);

  function handleDecrease() {
    if (number > 0) {
      SetNumber(number - 1);
    }
  }

  return (
    <View style={styles.container}>
      <TouchableOpacity onPress={handleDecrease} activeOpacity={0.7}>
        <Icon name="minus" size={20} color={colors.white} style={styles.icon} />
      </TouchableOpacity>
      <AppText style={styles.text}>{number}</AppText>
      <TouchableOpacity onPress={handleIncrease} activeOpacity={0.7}>
        <Icon name="plus" size={20} color={colors.white} style={styles.icon} />
      </TouchableOpacity>
    </View>
  );
}

欢迎任何其他建议。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM