【问题标题】:How to re-render screen on click in React Native Navigation?如何在 React Native Navigation 中点击时重新渲染屏幕?
【发布时间】:2022-11-18 07:25:04
【问题描述】:

我在 React Native Navigation 屏幕内有一个矩形,我想在每次用户单击该特定屏幕时为其设置动画。现在它只播放一次动画,当应用程序第一次呈现时。我看到有多个解决方案适用于其他人解决此类问题,但没有一个适用于我 - 应用程序不会在点击时重新呈现。我究竟做错了什么?

设置Screen.js(屏幕切换需要重新渲染的动画)

const { width } = Dimensions.get("screen");

const SettingsScreen = () => {
  return (
    <FlatList
      contentContainerStyle={style.barContainer}
      data={[1, 2, 3, 4, 5]}
      keyExtractor={(_, index) => index.toString()}
      renderItem={() => <ProgressBar />}
    ></FlatList>
  );
};

const ProgressBar = () => {
  const isFocused = useIsFocused();

  const barWidth = React.useRef(new Animated.Value(0)).current;

  console.log(barWidth);

  const finalWidth = width / 2;

  React.useEffect(() => {
    Animated.spring(barWidth, {
      toValue: finalWidth,
      bounciness: 10,
      speed: 2,
      useNativeDriver: false,
    }).start();
  }, [isFocused]);

  return (
    <View style={style.contentContainer}>
      <Animated.View style={[style.progressBar, { width: barWidth }]} />
    </View>
  );
};

MainContainer.js(设置所有导航的地方)

const profileName = "Profile";
const detailsName = "Details";
const settingsName = "Settings";
const profileNameFR = "P";
const detailsNameFR = "D";
const settingsNameFR = "S";

const Tab = createBottomTabNavigator();

export default function MainContainer() {
  const { locale } = useContext(LanguageContext);
  
  return (
    <NavigationContainer>
      <Tab.Navigator
        screenOptions={({ route }) => ({
          tabBarIcon: ({ focused, color, size }) => {
            let iconName;

            let rn = route.name;

            if (rn === profileName || rn === profileNameFR) {
              iconName = focused ? "person" : "person-outline";
            } else if (rn === detailsName || rn === detailsNameFR) {
              iconName = focused ? "list" : "list-outline";
            } else if (rn === settingsName || settingsNameFR) {
              iconName = focused ? "settings" : "settings-outline";
            }

            return <Ionicons name={iconName} size={size} color={color} />;
          },
          tabBarActiveTintColor: "tomato",
          inactiveTintColor: "grey",
          tabBarStyle: { padding: 10, height: 60 },
          tabBarLabelStyle: { paddingBottom: 10, fontSize: 10 },
          style: { padding: 10 },
        })}
      >  

【问题讨论】:

  • 您使用的是哪个版本的反应导航?
  • "@react-navigation/bottom-tabs": "^6.4.0", "@react-navigation/native": "^6.0.13", "@react-navigation/stack": "^6.3.4",

标签: reactjs react-native react-navigation react-animated


【解决方案1】:

发生这种情况是因为 FlatList 是一个 PureComponent,这意味着如果 props 保持不变,它将不会重新渲染。因此,在这种情况下,请尝试在 SettingsScreen 组件内使用 useIsFocused 钩子,并将其作为道具传递给 ProgressBar。

内部设置屏幕:

const isFocused = useIsFocused();

...

<FlatList
 ...
 renderItem={() => <ProgressBar isFocused={isFocused} />}

此外,不建议使用 useIsFocused 钩子,因为这将不必要地多次重新渲染您的组件。相反,您可以使用事件侦听器来侦听“焦点”事件,如下所示:

React.useEffect(() => {
 const listener = navigation.addListener('focus', () => {
    Animated.spring(barWidth, {
      toValue: finalWidth,
      bounciness: 10,
      speed: 2,
      useNativeDriver: false,
    }).start();
 });

 return listener;
}, [navigation])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-11-30
    • 2021-06-12
    • 2018-09-02
    • 2020-03-21
    • 2018-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多