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