#javascript #reactjs #react-hooks #use-state
Вопрос:
В настоящее время я создаю страницу профиля, на которой она изначально будет получать сведения о профиле пользователя из конечной точки API. Я хочу, чтобы индикатор загрузки отображал статус выборки. Сейчас я использую хук useState, где я сохраняю логическое значение для состояния загрузки. Однако, прочитав документацию об использовании, он заявил, что она может быть асинхронной. Следовательно, как мне правильно обновить isLoading до true, а затем выполнить логику выборки? Прямо сейчас вот мой фрагмент кода.
function Profile() { const [isLoading, setIsLoading] = useState(false); const [user, setUser] = useState(null); const { username } = useParams(); const fetchUserDetails = async (username) =gt; { setIsLoading(true); try { const userRes = await API.graphql({ query: queries.getUser, variables: { username }, }); if (userRes.error) { throw new Error({ cause: userRes.error }); } setUser(userRes.data.getUser); setIsLoading(false); } catch (error) { console.error(error); // push to error page setIsLoading(false); } }; // Fetch user profile data useEffect(() =gt; { fetchUserDetails(username); }, []); ...
Комментарии:
1. Но в таком случае оба являются aysnc, верно? Это означает, что fetchUserDetails может произойти или не произойти после обновления загрузки @AbdulahProho
2. Возможно, поскольку вы запускаете это только на начальном монтировании,
isLoading
true
для начала следует установить значение, затемuseEffect
выполнить и установить егоfalse
по завершении.3. @pilchard, это сработало бы! Но что, если все наоборот? Как бы вы подошли к такому варианту использования
Ответ №1:
В вашем примере использования вы можете просто установить isLoading
значение true
изначально и запустить выборку на монтировании.
function Profile() { const [isLoading, setIsLoading] = useState(true); const [user, setUser] = useState(null); const { username } = useParams(); // Fetch user profile data useEffect(() =gt; { const fetchUserDetails = async (username) =gt; { try { const userRes = await API.graphql({ query: queries.getUser, variables: { username }, }); if (userRes.error) { throw new Error({ cause: userRes.error }); } setUser(userRes.data.getUser); setIsLoading(false); } catch (error) { console.error(error); // push to error page setIsLoading(false); } }; fetchUserDetails(username); }, []);
но если вы хотите следить за изменениями isLoading
, например, для кнопки перезагрузки, вы можете установить ее false
изначально, установить значение true в эффекте использования при монтировании и сделать так, чтобы эффект извлечения зависел от isLoading
function Profile() { const [isLoading, setIsLoading] = useState(false); const [user, setUser] = useState(null); const { username } = useParams(); // set isLoading to true on-mount useEffect(() =gt; { setIsLoading(true) },[]); // Fetch user profile data useEffect(() =gt; { const fetchUserDetails = async (username) =gt; { try { const userRes = await API.graphql({ query: queries.getUser, variables: { username }, }); if (userRes.error) { throw new Error({ cause: userRes.error }); } setUser(userRes.data.getUser); setIsLoading(false); } catch (error) { console.error(error); // push to error page setIsLoading(false); } }; if (isLoading) { fetchUserDetails(username); } }, [isLoading]); function triggerReload() { setIsLoading(true) }
Ответ №2:
идея состоит в том, чтобы обновить начальную загрузку до true внутри функции выборки, и вы сделали это правильно. чего не хватает, так это добавить, если условие внутри эффекта использования при загрузке верно, а затем получить сведения о пользователе.
useEffect(() =gt; { if(isLoading){ fetchUserDetails(username); } }, [isLoading])
это приведет к выборке, если условие верно.
Комментарии:
1. Интересно, что одна из проблем будет заключаться в том, что fetchUserDetails вообще не будет выполняться, возможно, в этом случае, поскольку мое начальное значение isLoading равно false
2. да, fetchUserDetails не будет выполняться, пока условие ложно. вам не нужно, чтобы он выполнялся, так как в нем есть ложные условия, верно?
3. Начальное состояние является ложным