#reactjs #react-hooks
#reactjs #реагирующие крючки
Вопрос:
У меня вызван пользовательский крючок useAddFriend
, вот код:
import { useCallback, useState } from 'react'
import { Users }from '../data/userDummy'
const useAddFriend = () => {
const [roomId, setRoomId] = useState("default")
const findUser = useCallback((username) => {
for(let user of Users) {
if(username === user.username) {
setRoomId("newRoomId")
}
}
}, [])
return { roomId, findUser }
}
export default useAddFriend;
Проблема в том, setRoomId
что никогда не обновляйте roomId. Я уже убедился, что он удовлетворил if condition
вышеуказанному. Но он всегда возвращается default
.
Вот как я использую крючок для компонента React:
const AddFriend = () => {
const [username, setUsername] = React.useState('')
const { roomId, findUser } = useAddFriend()
const history = useHistory()
const handleInputChange = (event) => {
setUsername(event.target.value)
}
const handleAddFriend = () => {
findUser(username)
setUsername("")
history.push(`/${roomId}`)
}
...
}
Ответ №1:
Я думаю, причина здесь:
const handleInputChange = (event) => {
setUsername(event.target.value)
}
const handleAddFriend = () => {
findUser(username)
setUsername("")
history.push(`/${roomId}`) // <= This line may execute before the roomId is fully set
}
Чтобы убедиться, что вы получите правильное roomId
значение после выполнения крючка, рекомендуется использовать вместе с useEffect
const handleAddFriend = () => {
findUser(username)
setUsername("")
}
useEffect(()=> { if(roomId!=='default') history.push(`/${roomId}`) }, [roomId]);
Комментарии:
1. Спасибо!! Никогда не думал, что эта проблема была вызвана
history
. Не могли бы вы сказать мне, почему или дать мне какую-нибудь ссылку. Заранее спасибо2. Выполняется ли перехват асинхронно?
3. @AlifRamdani useState (то же самое с setState в class-component) является асинхронным. И они, как правило, выполняют несколько обновлений за один раз. Поэтому не совсем надежно, если мы рассматриваем их как синхронные и рекомендуем использовать useEffect, как я только что упомянул
4. Ах, я забыл, что setState является асинхронным. Спасибо
Ответ №2:
Вам нужно удалить useCallback или передать аргумент, который вы хотите обновить, в квадратных скобках
const findUser = useCallback((username) => {
for(let user of Users) {
if(username === user.username) {
setRoomId("newRoomId")
}
}
}, [roomId])
Комментарии:
1. Привет @Max, не могли бы вы добавить сюда несколько ссылок или еще несколько пояснений?
2. reactjs.org/docs/hooks-reference.html#usecallback
3. можете ли вы удалить history.push?
4. @Max Я пробовал, и это все еще не работает. И я также уверен, что это не имеет никакого отношения к проблеме