微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React Native setState 根本不工作功能组件,甚至不同步

如何解决React Native setState 根本不工作功能组件,甚至不同步

我感谢任何人花时间检查我的代码并帮助我解决问题(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,-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 本身中进行控制台登录,并且确信下拉列表的值确实发生了变化,所以只是状态管理出了问题。

感谢任何帮助! :)

解决方法

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

,

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

由于 setState 函数是异步的,您可以使用 useEffect 钩子来实现您正在寻找的功能。

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

},[appLanguage])

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。