Эффект использования в пользовательском крючке замораживает мое собственное приложение react, когда крючок используется более чем в одном месте

#reactjs #react-native

Вопрос:

Я создал пользовательский хук, который извлекает настройки из api, использующего асинхронное хранилище.

 // Takes the key/name of the setting to retrieve
export const useSettings = (key) => {

  // stores the json string result in the setting variable
  const [setting, setSetting] = useState("");

  const deviceStorage = useContext(DeviceStorageContext);

  useEffect(() => {
    getValue()
     .then(value => setSetting(value));
  }, []);

  // gets value from my custom api that uses Async-Storage to handle r/w of the data.
  const getValue = async () => await deviceStorage.getValueStored(key);
  
  const setValue = async (value) => { 
      await deviceStorage.setValueStored(key, value);
      getValue().then(value => setSetting(value));
  };

  
  const removeValue = async () => { }

  return [setting, { setValue,removeValue }];
};
 

Это работает, как и ожидалось, в Main.jsx без каких-либо проблем.

 const Main = () => {
  const [units, operations] = useSettings('units');

  useEffect(() => {
    const initSettings = async () => {
      if (units) {
       console.log(units)
       return;
     }
      await operations.setValue({ pcs: 1, box: 20 });
    };
    initSettings();
  }, []);
 

Однако, когда я даже просто вызываю крючок настройки в Form.jsx и посещаю страницу, все мое приложение зависает только на этой странице.

 const FormView = ({ handleReset, handleSubmit }) => {
  const [setting,] = useSettings('units');
 

Удаление useState и useEffect исправляет это, и прямой вызов этих методов работает, но я действительно не хочу вызывать GetValue() на протяжении всего моего проекта и использовать асинхронный/ожидающий код для его обработки.

Застрял на этом уже несколько часов. Любая помощь будет оценена по достоинству.

Спасибо.

Комментарии:

1. Добро пожаловать @иностранный-родной. Можете ли вы проверить свой рендеринг? Является ли ваш пользовательский хук или что-то в этом роде блокировкой вашего приложения из-за какого-то цикла повторного рендеринга в useEffect?

2. @Крис, спасибо тебе. Я уже пробовал это. Кажется, что все отображается нужное количество раз без каких-либо проблем, за исключением эффекта использования в настройках использования. Я попробовал поставить консоль. войдите в журнал, чтобы узнать, сколько раз он вызывается, но он ничего не печатает. Я предполагаю, что именно здесь он застревает в бесконечном цикле, но я не могу понять, почему.

3. на самом деле это звучит так, как будто вы не видите консоль. бревно вообще не стреляет? Если бы вы видели консоль. регистрируйте тонну, вы бы знали, что она была в замкнутом цикле. Также в вашем фрагменте кода формы вы, вероятно, просто не скопировали, но для ясности вы закрыли FormView с помощью } правильно?

4. @Крис, Да. Я закрыл FormView. После этого он просто отображает форму. Я должен уточнить значение GetValue().тогда() внутри моего эффекта использования ничего не печатает. Он печатается при вызове Main.jsx, но не при вызове FormView. Я попробовал поставить консоль. войдите в GetValue, это тогда и его улов. Никто из них ничего не печатает. Кроме того, сам useEffect отлично печатается даже в FormView.

5. @Крис Нвм. Это была выпадающая библиотека внутри FormView, которая все испортила. Удаление этой библиотеки исправило это. Я все еще не понимаю, почему. Он никак не использовал этот крючок и беспокоился только тогда, когда этот крючок использовался. Спасибо за помощь. Очень признателен.

Ответ №1:

Это была выпадающая библиотека компонентов внутри FormView, которая все испортила. Удаление этой библиотеки исправило это.