【问题标题】:React Native setState not working (functional component) at all, not even just out of syncReact Native setState 根本不工作(功能组件),甚至不同步
【发布时间】:2021-03-29 18:46:55
【问题描述】:

感谢任何花时间检查我的代码并帮助我解决问题的人(printLang() 总是打印“en”或“es”,具体取决于我刷新应用程序时它所采用的值)!我是第一次使用Material Dropdown,不知道会不会影响到我的状态管理,所以我把整个代码贴在这里!

import React, { useCallback, useState } from 'react';

const LANGS = [
    {
        value: 'en',
    }, 
    {
        value: 'es',
    }
];

const INTRO_DATA = [
    {
        key: '1',
        title: 'Language Selection',
        description: 'Choose your preferred language',
    },
    {
        key: '2',
        title: 'Role Selection',
        description: 'Are you a worker or a organization / business owner?',
    }
];

const IntroScreen = ({navigation}) => {
    const [appLanguage, setAppLanguage] = useState("en");
    const { width } = Dimensions.get('screen');
    const scrollX = React.useRef(new Animated.Value(0)).current;

    const printLang = () => {
        if (appLanguage == "en") {
            setAppLanguage("es");
        }
        else {
            setAppLanguage("en");
        }
        console.log(appLanguage);
    }

    const languageSelectionDropdown = (
        <View style={styles.test}>
            <Dropdown 
                width={150} 
                maxHeight={150} 
                label='Language' 
                data={LANGS}
                onChangeText={(value, index, data) => {
                    console.log(value);
                    console.log(index);
                    console.log(data);
                    () => {setAppLanguage(value)};
                }}
                baseColor={Colors.darkGray}
                textColor={Colors.darkGray}
                containerStyle={styles.dropDownStyle}
            />
            <TouchableOpacity style={styles.touchable} onPress={() => printLang()}>
                <Text>
                    Next
                </Text>
            </TouchableOpacity>
        </View>
    );

    const testmodule = (
        <View style={styles.buttonsContainer}>
            <Text>Empty for now</Text>
        </View>
    );
    
    const renderItem = React.useCallback(
        ({ item, index }) => {
            const inputRange = [
                (index - 1) * width,
                index * width,
                (index + 1) * width,
            ];
            const descriptionTranslate = scrollX.interpolate({
                inputRange,
                outputRange: [width * 0.1, 0, -width * 0.1],
            });
            return (
                <View style={[styles.itemContainer, { width: width - 80 }]}>
                    <Text style={styles.title}>{item.title}</Text>
                    <Animated.Text style={{ transform: [{ translateX: descriptionTranslate }] }}>
                        {item.description}
                    </Animated.Text>
                    <View>
                        {item.key == '1' ? languageSelectionDropdown : testmodule}
                    </View>
                </View>
            );
        },
        [scrollX, width]
    );

    const keyExtractor = React.useCallback((item) => item.key, []);

    return (
        <View style={[styles.container]}>
          <FlatList
            data={INTRO_DATA}
            keyExtractor={keyExtractor}
            showsHorizontalScrollIndicator={false}
            onScroll={Animated.event(
              [{ nativeEvent: { contentOffset: { x: scrollX } } }],
              {
                useNativeDriver: false,
              }
            )}
            style={styles.flatList}
            pagingEnabled
            horizontal
            decelerationRate={'normal'}
            scrollEventThrottle={16}
            renderItem={renderItem}
          />
          <View style={styles.text}>
            <View style={styles.dotContainer}>
              <Text>Scaling Dot</Text>
              <ScalingDot
                data={INTRO_DATA}
                scrollX={scrollX}
                containerStyle={{
                  top: 30,
                }}
              />
            </View>
          </View>
        </View>
      );    
};

在应用程序的任何单次运行中,languageSelectionDropdown 中的按钮调用 printLang() 并始终打印相同的值,即使我使用下拉菜单在语言之间切换也是如此。我已经尝试在onChangeText 中进行控制台登录,并且确信下拉列表的值确实在发生变化,所以只是状态管理出了问题。

感谢任何帮助! :)

【问题讨论】:

    标签: javascript react-native react-functional-component react-state-management


    【解决方案1】:

    您似乎忘记将 languageSelectionDropdown 作为依赖项添加到您的 renderItem 函数与 useCallback。由于您没有添加它,所以renderItem 函数永远不会看到状态的变化,这就是为什么总是给您相同的值。

    【讨论】:

    • 感谢它的工作!是的,看了你的回复我才知道!对于任何想知道的人,我刚刚将[scrollX, width] 更改为[scrollX, width, appLanguage]
    【解决方案2】:

    状态会异步更新,因此printLang() 函数在组件重新呈现之前不会看到更改。

    因为setState函数是异步的,所以可以使用useEffect钩子来实现你想要的功能。

    useEffect(() => { 
     // call any function you want to
     // this will only execute after appLanguage is updated. 
    
    },[appLanguage])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 2022-11-29
      • 1970-01-01
      相关资源
      最近更新 更多