reactjs 状态改变时,react-native-really-awesome-button onPress未更新函数

dced5bon  于 2022-11-04  发布在  React
关注(0)|答案(1)|浏览(148)

我安装了react-native-really-awesome-button包,因为它有一些非常棒的按钮。
不幸的是,onPress处理程序似乎没有按预期工作。
下面是一个可重现的演示:https://snack.expo.dev/@anshnanda/awesomebutton-not-working您可以清楚地看到,onPress函数只使用初始状态,并且没有使用新状态进行更新。
很明显,AwesomeButton只是使用了num的初始状态值,这让我认为该函数是用useMemouseCallback Package 的(可能有bug),然而,通过挖掘source code,我无法找到发生这种情况的原因。
我尝试使用onPressInonPressOut,这些似乎工作正常,除了UX显然更糟,因为用户没有看到我下载react-native-really-awesome-button的光滑动画。

x6yk4ghg

x6yk4ghg1#

看起来你是在要求确认这是AwesomeButton中的一个bug/问题,我同意这一点。
onPress回调存储在React引用中:(来源)

const debouncedPress = useRef(
  debouncedPressTime
    ? debounce(
        (animateProgressEnd: (callback?: any) => void) =>
          onPress(animateProgressEnd), // <-- here
        debouncedPressTime,
        {
          trailing: false,
          leading: true,
        }
      )
    : onPress // <-- here
);

press处理程序中调用debouncedPress:(来源)

const press = () => {
  actioned.current = true;
  if (progressing.current === true) {
    return;
  }

  if (progress === true) {
    requestAnimationFrame(startProgress);
  }

  debouncedPress.current(animateProgressEnd); // <-- here
};

presshandlePressOut回调调用:(来源)
animateProgressEnd处理程序调用传递的onPress函数(debouncedPress):(来源)

const animateProgressEnd = (callback: any) => { // <-- your callback
  if (progress !== true) {
    return;
  }

  if (timeout?.current) {
    clearTimeout(timeout.current);
  }

  requestAnimationFrame(() => {
    animateTiming({
      variable: animatedLoading,
      toValue: 1,
    }).start(() => {
      Animated.parallel([
        animateElastic({
          variable: textOpacity,
          toValue: 1,
        }),
        animateElastic({
          variable: activityOpacity,
          toValue: 0,
        }),
        animateTiming({
          variable: loadingOpacity,
          toValue: 0,
          delay: 100,
        }),
      ]).start(() => {
        animateRelease(() => {
          progressing.current = false;
          callback && callback(); // <-- called here
          onProgressEnd && onProgressEnd();
        });
      });
    });
  });
};

因此,是的,React ref debouncedPress永远不会更新,以保存您传递的onPress回调处理程序的较新示例。
要解决这个问题,可以在代码中使用React ref来缓存num状态,并在printCurrNum处理程序中引用它。
示例:

function App() {
  const [num, setNum] = React.useState(0);
  const [currentValue, setCurrentValue] = React.useState(0);

  const numRef = React.useRef(num); // <-- ref to cache num state
  React.useEffect(() => {           // <-- effect to update cache
    numRef.current = num;
  }, [num]);

  const increment = () => {
    setNum((num) => num + 1);
  };

  const printCurrNum = () => {
    console.log(numRef.current);     // <-- reference current value
    setCurrentValue(numRef.current); // <-- reference current value
  };

  return (
    <View style={styles.container}>
      <Text>Current value according to AwesomeButton: {currentValue}</Text>
      <Text>{num}</Text>
      <AwesomeButton onPress={printCurrNum}>
        Update current value with Awesome Button
      </AwesomeButton>
      <Button title="Increment" onPress={increment} />
      <Button
        title="Update current value with native button"
        onPress={printCurrNum}
      />
    </View>
  );
}

https://snack.expo.dev/@drew.w.reese/awesomebutton-not-working

相关问题