Неверный вызов перехвата, один работает, а другой нет

Я пытаюсь модульизировать свой код, поэтому пытаюсь разделить читаемые данные.

вот мой предыдущий код, который работает без ошибок:

function Home({navigation, route}): React.JSX.Element {
   const [showAddBillModal, setShowAddBillModal] = useState(false)
   const isDarkMode = useColorScheme() === 'dark';
   const backgroundStyle = {
      backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
    };

    const toggleShowAddBillModal = () => {
       setShowAddBillModal(!showAddBillModal)
  }

   // const user = getLoggedInUser() //works

    return (...)

но когда я пытаюсь сделать его модульным, разделив читаемые пользовательские данные в другой файл/класс:

страница авторизации:

const login = (text, navigation) =>{
let userData = getLoggedInUser(text)
if (userData !== null || userData !== undefined){
    () => navigation.navigate('Home', {user: userData})
}
}

function Login({ navigation }): React.JSX.Element {
const [name, onChangeNameText] = React.useState('');
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};

// const user = getLoggedInUser()
return (....
                <Pressable
                    style = {[styles.button, styles.buttonClose]}
                    onPress = {() => login(name, navigation)}
                    >...
)
}

файл для чтения данных:

export default getLoggedInUser = async (name) => {
const [userData, setUserData] = useState(null)
// const userData = null
try{
    console.info("test")
    await firestore()
        .collection('users')
        .get()
        .then(querySnapshot => {
            querySnapshot.forEach(doc => {
                if (doc.data().name == name) {
                    setUserData(doc)
                    // return doc
                    // userData = doc
                    // return userData
                }
            });
        });
        return userData
}
catch(error){
    console.info(error)
}
}

я получаю здесь неверный вызов на перехват я пробовал нормально выполнять функцию name() {hook ....}, но она также выдает ту же ошибку, она работает везде, кроме этой части

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

Drew Reese 06.04.2024 09:40

отредактировано, чтобы было понятнее

Wei Xiong 06.04.2024 10:43
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
2
55
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы не можете вызывать хуки React вне компонентов React или пользовательских хуков React, поскольку это нарушает Правила использования хуков React.

Вы можете преобразовать свою функцию getLoggedInUser в хук React, чтобы она также могла использовать хук useState. Я бы предложил вернуть функцию, которую пользовательский интерфейс может вызвать, чтобы инициировать выборку данных из вашего бэкэнда Firestore.

Пример реализации:

export default useGetLoggedInUser = () => {
  const [userData, setUserData] = useState(null);

  const getLoggedInUser = async (name) => {
    try {
      const users = await firestore()
        .collection('users')
        .get();

      let userData = null;
      querySnapshot.forEach(doc => {
        if (doc.data().name == name) {
          setUserData(doc);
        }
      });
        
      return userData;
    } catch(error) {
      console.info(error);
      // re-throw for callers
      throw error;
    }
  };
  
  return {
    userData,
    getLoggedInUser,
  };
}

Переместите обработчик login в компонент Login, чтобы закрыть name и navigator в области обратного вызова. Вызовите новый хук useGetLoggedInUser и получите доступ к возвращаемой функции getLoggedInUser, которая будет вызвана в обратном вызове login. await его возвращаемое значение и, если оно правдивое, выполнить действие навигации.

function Login({ navigation }): React.JSX.Element {
  const [name, onChangeNameText] = React.useState('');
  const isDarkMode = useColorScheme() === 'dark';

  const { getLoggedInUser } = useGetLoggedInUser();

  const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
  };

  const login = async () => {
    try {
      const user = await getLoggedInUser(name);

      if (user) {
        navigation.navigate('Home', { user });
      }
    } catch(error) {
      // handle/ignore/etc
    }
  };

  return (
    ...
    <Pressable
      style = {[styles.button, styles.buttonClose]}
      onPress = {login}
    >
      ...
    </Pressable>
  );
}

экспортный useGetLoggedInUser по-прежнему не работает из-за второй строки «useState», хотя я не знаю, почему сейчас не отображается никаких ошибок, console.infoging до того, как объявление usestate работает, но не после

Wei Xiong 06.04.2024 11:41

о, теперь я понимаю, что вы имеете в виду.... я никогда раньше не пытался создать собственный крючок, и мне никогда не приходило в голову это сделать, это решение тоже должно работать

Wei Xiong 06.04.2024 14:19
Ответ принят как подходящий

решил это, мой упрямый ум не додумался разместить хук usestate спереди целых 3 дня :D

страница авторизации:

function Login({ navigation }): React.JSX.Element {
    const [userData, setUserData] = useState(null)
    const login = async () => {
        try {
            console.info("presslogin")
        //   const user = await getLoggedInUser(name, setUserData);
        await getLoggedInUser(name, setUserData)
        // console.info(user)
        //   if (user) {
            navigation.navigate('Home', { userData });
        //   }
        } catch(error) {
          // handle/ignore/etc
        }
}

бэкэнд:

export default getLoggedInUser = async (name, setUserData) => {
try {
    const users = await firestore()
        .collection('users')
        .get()
        .then(querySnapshot => {
            querySnapshot.forEach(doc =>{
                if (doc.data().name == name) {
                    setUserData(doc);
                }
            })
    });
    // return userData;
} catch (error) {
    console.info(error);
    // re-throw for callers
    throw error;
}
}

я приму свой собственный ответ, но для тех, кто хочет увидеть решение с помощью специального хука, см. ответ Дрю Риза :)

изменить: usestate в конце концов у меня не сработало, так как это асинхронный... обновленный ответ ниже:

страница авторизации:

function Login({ navigation }): React.JSX.Element {
const [name, onChangeNameText] = React.useState('');
const isDarkMode = useColorScheme() === 'dark';
const backgroundStyle = {
    backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
};
const login = async () => {
    try {
        const userData = await getLoggedInUser(name)
        if (userData){
            navigation.navigate('Home', {userData})
        }
    } catch(error) {
      // handle/ignore/etc
    }
}

бэкэнд:

export default getLoggedInUser = async (name) => {
let userData = null
try {
    await firestore()
        .collection('users')
        .get()
        .then(querySnapshot => {
            querySnapshot.forEach(doc =>{
                if (doc.data().name == name.toLowerCase()) {
                    userData = doc
                }
            })
    });
    return userData;
} catch (error) {
    console.info(error);
    // re-throw for callers
    throw error;
}
}

Другие вопросы по теме