Я пытаюсь модульизировать свой код, поэтому пытаюсь разделить читаемые данные.
вот мой предыдущий код, который работает без ошибок:
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 ....}, но она также выдает ту же ошибку, она работает везде, кроме этой части
отредактировано, чтобы было понятнее



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


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