Как передать состояние и setState другой функции в качестве параметра? - PullRequest
0 голосов
/ 04 апреля 2020

Я определил объект начального состояния глобально, как показано ниже.

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

Теперь внутри метода useEffect () я вызываю некоторую функцию, которая будет выполнять некоторые вызовы API бэкэнда и основываясь на ответе i. нужно установить объекты состояния, я попытался, как показано ниже.

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": {}}

Не могли бы вы помочь или дать некоторые рекомендации о том, как этого добиться?

1 Ответ

1 голос
/ 04 апреля 2020

Если позже использовать «обновленное» значение состояния в той же функции, вы можете создать объект, представляющий следующее состояние, передать его в обратный вызов setState и использовать вместо него it для будущих сравнений.

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);
    });
}

Альтернатива

Вы также можете немного разбить эту логику c, сохраняя все от до первого вызова обновления состояния в каждая логика c ветка checkConfigStorage, и просто обновить это состояние и вернуться. В компоненте примените дополнительные эффекты, которые имеют эти значения состояния как зависимости, чтобы затем выполнить logi c после этого первого обновления. По сути, используйте ловушки эффектов, чтобы «связать» обновления зависимых состояний. IE newConfigState обновлен, запустите ловушку эффекта, чтобы проверить newConfig.data.update.version_code > AppC.current_version_code и вызвать setNewForceUpdate, и так далее.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...