0

我已经在全局范围内定义了初始状态对象,如下所示。

   //states related code
    const [newConfigState, setNewConfig] = useState({config: {}});
    //force update states
    const [newForceUpdate, setNewForceUpdate] = useState({ forceUpdate:false, popupCancelable:false});

现在在 useEffect() 方法中,我调用了一些函数,它将执行一些后端 api 调用,并根据我需要设置状态对象的响应,我尝试如下。

useEffect(() => {
        checkConfigStorage(setNewConfig, newConfigState, setNewForceUpdate, newForceUpdate);
    }, []);
  1. 这是传递给函数以设置状态的正确方法吗?

现在里面的代码checkConfigStorage(setNewConfig, newConfigState, setNewForceUpdate, newForceUpdate)如下:

export async function checkConfigStorage(setNewConfig, newConfigState, setNewForceUpdate, newForceUpdate) {
    AsyncStorage.getItem(Constants.CONFIG)
        .then(configstr => {
            // console.log("CNG CALLED GETITEM", configstr);
            //console.log("GLOBAL CONFIG", global.config);
            let config;
            if (configstr != null) {
                config = JSON.parse(configstr);
                console.log(config);
                if (config !== null &&
                    config.data !== null &&
                    config.data !== undefined) {
                    **setNewConfig({...newConfigState, config: {config}});**
                    if (
                        global.config === undefined &&
                        newConfigState.data !== null
                    ) {
                        global.config = newConfigState.data;
                    }
                    console.log("newConfig", newConfigState);
                    let userInfoObj = {};
                    userInfoObj.userid = userid;
                    userInfoObj.sessionid = sessionid;


                    if (newConfigState.data != null && newConfigState.data.update.version_code > AppC.current_version_code) {
                        //show popup
                        **setNewForceUpdate(...newForceUpdate, {
                            forceUpdate: newConfigState.data.update.force_update,
                            popupCancelable: newConfigState.data.update.allow_cancel
                        });**
                    }
                } else {
                    global.config = backupConfig;
                    **setNewConfig(...newConfigState, {config: backupConfig});**
                    console.log("CONFIG stored in AsyncStorage seems NULL", config.data);
                    console.log("So getting it from backup and setting to state", newConfigState.data);
                }
            }
        })
        .catch(err => {
            console.log("HOME 1 Error", err);
            var error = {
                err: err,
                msg: "Error : HomeScreen: checkconfig"
            };
            global.config = backupConfig;
            **setNewConfig({...newConfigState, {config: backupConfig}});**
            console.log("Caught in the catch block, assigning backup config", newConfigState.data);
            // MyEventLogger.logEventAndDesc("ERROR", error);
        });
}

但问题是新值被分配给状态对象。当我尝试在控制台中打印状态对象值时,它显示如下,我在开始时初始化了哪个空对象。

newConfig {"config": {}}

您能否就如何实现这一目标提供帮助或提供一些指导?

4

1 回答 1

1

如果稍后在同一函数中使用“更新的”状态值,您可以创建一个表示下一个状态的对象,将其传递给 setState 回调,并将用于将来的比较。

export async function checkConfigStorage(
  setNewConfig,
  newConfigState,
  setNewForceUpdate,
  newForceUpdate
) {
  AsyncStorage.getItem(Constants.CONFIG)
    .then(configstr => {
      // console.log("CNG CALLED GETITEM", configstr);
      //console.log("GLOBAL CONFIG", global.config);
      let config;
      if (configstr != null) {
        config = JSON.parse(configstr);
        console.log(config);
        if (
          config !== null &&
          config.data !== null &&
          config.data !== undefined
        ) {
          // save new config for further usage
          const newConfig = { ...newConfigState, config };
          // setNewConfig({...newConfigState, config: {config}});
          setNewConfig(newConfig);
          if (global.config === undefined && newConfig.data !== null) {
            global.config = newConfig.data;
          }
          console.log("newConfig", newConfig);
          let userInfoObj = {};
          userInfoObj.userid = userid;
          userInfoObj.sessionid = sessionid;

          if (
            newConfig.data != null &&
            newConfig.data.update.version_code > AppC.current_version_code
          ) {
            //show popup
            setNewForceUpdate(...newForceUpdate, {
              forceUpdate: newConfig.data.update.force_update,
              popupCancelable: newConfig.data.update.allow_cancel
            });
          }
        } else {
          global.config = backupConfig;
          const newConfig = { ...newConfigState, backupConfig };
          setNewConfig(newConfig);
          console.log("CONFIG stored in AsyncStorage seems NULL", config.data);
          console.log(
            "So getting it from backup and setting to state",
            newConfig.data
          );
        }
      }
    })
    .catch(err => {
      console.log("HOME 1 Error", err);
      var error = {
        err: err,
        msg: "Error : HomeScreen: checkconfig"
      };
      global.config = backupConfig;
      const newConfig = { ...newConfigState, backupConfig };
      setNewConfig(newConfig);
      console.log(
        "Caught in the catch block, assigning backup config",
        newConfig.data
      );
      // MyEventLogger.logEventAndDesc("ERROR", error);
    });
}

替代

您还可以稍微分解一下这个逻辑,让所有内容都保持在 的每个逻辑分支中的第一个状态更新调用checkConfigStorage然后简单地更新该状态并返回。在组件中,应用更多具有这些状态值作为依赖项的效果挂钩,然后在第一次更新执行逻辑。本质上使用效果挂钩来“链接”相关状态更新。IEnewConfigState更新,运行效果挂钩检查newConfig.data.update.version_code > AppC.current_version_code和调用setNewForceUpdate,等等。

于 2020-04-04T08:10:43.473 回答