Useeffect 不会随着依赖值的变化而立即被调用

Useeffect not getting called immedietly as dependency value changes

我对反应很陌生。我现在正在试验 React 并试图理解它的概念。

我有一个组件有两个状态,名称和房间。我正在使用 setstate 来设置房间和名称值,我有 2 个 useeffects 第一个在初始渲染时运行并获取名称和房间值。第二个应该在名称或房间更改后立即呈现

const Chat = ({location}) => {
    const [userName, setUserName] = useState("");
    const [userRoom, setUserRoom] = useState("");
    useEffect(() => {
        // console.log("initial use effect called")
        const {name,room} = queryString.parse(location.search)
        setUserName(name)
        setUserRoom(room)
    }, [])
    useEffect(()=>{
        console.log('name or room changed')
    },[userName,userRoom])
    return (

        <div>
           component
        </div>
    )
}

因为我是一个接一个地设置name和room我希望第二次使​​用效果被调用3次

(第一次在初始渲染时,第二次在名称更改时,第三次在房间更改时)

但只调用了两次。 另外,如果我在初始使用效果中添加超时,[​​=12=]

第二个 useeffect 被调用了 3 次

const Chat = ({location}) => {
    const [userName, setUserName] = useState("");
    const [userRoom, setUserRoom] = useState("");
    useEffect(() => {
        // console.log("initial use effect called")
        const {name,room} = queryString.parse(location.search)
        setUserName(name)
        setTimeout(()=>{
        setUserRoom(room)
          },0)
        
    }, [])
    useEffect(()=>{
        console.log('name or room changed')
    },[userName,userRoom])
    return (

        <div>
           component
        </div>
    )
}

React 批量更新状态。这意味着,当您多次设置状态时,它将在一次操作中更新两个状态,从而减少重新渲染(这在大多数情况下是好的)。您可以了解更多有关此内容的信息 here

setStateReact事件处理程序或同步生命周期方法中被多次调用时,它将被批处理为一个更新。这就是为什么你得到两个日志,initial render 导致第一个日志和 setState 导致第二个日志 并且当你在 setTimeOut 中调用 useState 然后它按你预期的那样记录,因为setTimeOut 是一个异步操作,它与其他异步操作(例如async/await, then/catch, fetch,等)的行为类似。因为单独的状态更新不会被批处理在异步操作中.