【问题标题】:useEffect can't update the stateuseEffect 无法更新状态
【发布时间】:2021-10-25 15:49:32
【问题描述】:

我有一部分代码加载了 i18n 的存储语言。 我正在尝试获取语言,将状态更改为 true,然后在屏幕上显示页面。

代码没有更新“yesLanguage”状态,它仍然返回 false..

代码必须返回 TRUE“yesLanguage”。

代码的目标是在显示屏幕之前设置应用程序的默认语言,然后以默认语言(用户最近设置的语言)显示屏幕。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */
/*
 import React from 'react';
 import {Text} from 'react-native';

  //import {SignUpScreen} from './src/components/PlayAround/ResponsiveLayout';
  import {HomeScreen} from './src/screens/HomeScreen';
 
 
  function App (props){
    return(
      <HomeScreen />
    );
  }
  
  
  
  export default App;
  */

import React,{useState,useEffect} from 'react';
import  './translations/i18n';
import {View, Text,Pressable} from 'react-native';
import {useTranslation} from 'react-i18next';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {HomeScreen} from './src/screens/HomeScreen';
import 'intl-pluralrules';



function App(props){


const {t, i18n} = useTranslation();
const [currentLanguage,setLanguage] = useState('ar');
const [yesLanguage , setYesLanguage] = useState(false);





const changeLanguage = value => {
    
    
    i18n
    .changeLanguage(value)
    .then(() => setLanguage(value))
    .catch(err => console.log(err));
    AsyncStorage.setItem('currentLnaguage',value);
    
};


React.useEffect(()=>{
    AsyncStorage.getItem('currentLnaguage').then(val => {
        
        //console.log(val+'useeee2');
        let newDefaultLang = val ? val :"ar"; // or Change ar with the default language
        i18n.locale = newDefaultLang;
        changeLanguage(newDefaultLang);
        //
        setYesLanguage(true);
        console.log(newDefaultLang+"qqqq");
    });
    
},[]);

console.log(yesLanguage);
//AsyncStorage.clear();
return yesLanguage && <HomeScreen buttonTitle={t('ordernow')} deliveryText={t('delivery')} />

};

export default App;


更新 这是我的 i18n 文件代码

import i18n from 'i18next';
import {initReactI18next} from 'react-i18next';
//import LanguageDetector from 'i18next-browser-languagedetector';
import en from './en/en.json';
import ar from './ar/ar.json';
import he from './he/he.json';
import AsyncStorage from '@react-native-async-storage/async-storage';
import React from 'react';


/*
i18n
.use(initReactI18next).init({
  lng: 'en',
  fallbackLng: 'en',
  resources: {
    en: en,
    ar: ar,
  },
  interpolation: {
    escapeValue: false // react already safes from xss
  }
});*/


const getDefaultLang = async () => {

  
  
  const storedLang = await AsyncStorage.getItem('currentLnaguage');
  
  
  /*if(storedLang!= null){
    i18n.defaultLocale = storedLang;
    i18n.locale = storedLang;
    i18n.fallbacks = true;
  }*/

  

  return i18n
    .use(initReactI18next) 
    .init({
      resources: {
        en: en,
        ar: ar,
        he: he
      },
      lng: storedLang ? storedLang : 'ar', 
      //lng: storedLang || "ar",
      interpolation: {
        escapeValue: false, 
      },

      fallbackLng: ['en', 'ar','he'],
    });
};

export default getDefaultLang();

【问题讨论】:

  • useEffect需要添加依赖
  • 他的useEffect会运行一次,这就是他想要的。问题可能是您的异步​​任务没有您的应用程序的上下文。想试试,可以console.log(setYesLanguage)看看你有什么资料!
  • 这个console.log(newDefaultLang+"qqqq");工作正常吗?
  • @AbuSufian 是的,它工作正常
  • @Melvynx 我得到 [函数绑定 dispatchAction]

标签: reactjs react-native rxjs react-hooks


【解决方案1】:

如果 useEffect 不起作用,请使用 useFocusEffect

import { useFocusEffect } from '@react-navigation/native';

useFocusEffect(
        React.useCallback(() => {
            // your code here
        }, [])
    );

【讨论】:

  • Hooks 只能在函数组件内部调用,所以会报错
【解决方案2】:

需要进行一些 useEffect 依赖项更改,它会像魅力一样工作。

看看下面的代码有什么变化,让我知道它是否有效。

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 * @flow strict-local
 */

import React,{useState,useEffect} from 'react';
import  './translations/i18n';
import {useTranslation} from 'react-i18next';
import AsyncStorage from '@react-native-async-storage/async-storage';
import {HomeScreen} from './src/screens/HomeScreen';
import 'intl-pluralrules';

function App(props){

    const {t, i18n} = useTranslation();
    const [currentLanguage,setLanguage] = useState('ar');
    const [yesLanguage , setYesLanguage] = useState(false);

    const changeLanguage = React.useCallback(async value => {
        i18n
        .changeLanguage(value)
        .then(() => setLanguage(value))
        .catch(err => console.log(err));
        await AsyncStorage.setItem('currentLnaguage',value);
    }, []);

    React.useEffect(()=>{
        AsyncStorage
        .getItem('currentLnaguage')
        .then(val => {
            let newDefaultLang = val ? val :"ar"; // or Change ar with the default language
            i18n.locale = newDefaultLang;
            changeLanguage(newDefaultLang);
            setYesLanguage(true);
            console.log(newDefaultLang+"qqqq");
        });
    },[changeLanguage]);

    console.log(yesLanguage);
    return yesLanguage && <HomeScreen buttonTitle={t('ordernow')} deliveryText={t('delivery')} />
};

export default App;

【讨论】:

  • 谢谢,但我得到的错误渲染钩子比上一次渲染时更多
  • @MikhaMatta 我对代码做了一些更改,请再试一次。
  • 谢谢..我还有一个问题:undefined is not an object (evalating prevDeps.length)
  • @MikhaMatta 我认为上述代码不会发生此错误,因为它的代码未访问任何 prevDeps.length 属性,它必须在其他地方
猜你喜欢
  • 2019-09-23
  • 1970-01-01
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2023-03-22
  • 2020-06-07
相关资源
最近更新 更多