简体   繁体   English

为什么我的反应钩子 state 只在两次点击后更新

[英]why my react hook state only update after two clicks

import React, { useState, useEffect } from 'react'
import './mobileNavBar.scss'
import { div } from 'react-router-dom'
import URL from '../../constant/urls'
import { openMobileMenu } from 'component/sideMenu/action/sideMenuAction'
import { bindActionCreators } from 'redux'
import { connect } from 'react-redux'
import classnames from 'classnames'

const MobileNavBar = () => {
    const [state, setState] = useState({
        home: true,
        cat: false,
        checkout: false,
    })
    useEffect(() => {
        detectLink()
    }, [])
    const detectLink = () => {
        const path = window.location.pathname
        if (path == '/') {
            setState((current) => ({
                ...current,
                home: true,
                cat: false,
                checkout: false,
            }))
            return
        }
        if (path.includes('cat')) {
            setState((current) => ({
                ...current,
                home: false,
                cat: true,
                checkout: false,
            }))
            return
        }
        if (path.includes('checkout')) {
            setState((current) => ({
                ...current,
                home: false,
                cat: false,
                checkout: true,
            }))
            return
        }
    }
    const handleClick = () => {
        detectLink()
    }
    const homecss = classnames({ active: state.home })
    const catcss = classnames({ active: state.cat })
    const checkoutcss = classnames({ active: state.checkout })
    return (
        <div className="mobileNav">
            <Link to='/' onClick={handleClick} className={'item ' + homecss}></Link>
            <Link to='/cat' onClick={handleClick} className={'item ' + catcss}></Link>
            <Link to='/checkout' onClick={handleClick} className={'item ' + checkoutcss}></Link>
        </div>
    )
}

I got a menu look like this.我有一个像这样的菜单。 I want when I click the menu item, css class active will be assigned to the item.我想当我点击菜单项时,css class active将分配给该项目。

problem is, one click will not make that happen, I need to double click.问题是,单击不会发生这种情况,我需要双击。 it seems the state is lagging, it seems it only updates when I trigger the next action. state 似乎滞后,它似乎只在我触发下一个动作时更新。

My guess is that window.location.pathname is not updated before the render.我的猜测是window.location.pathname在渲染之前没有更新。 But there's a lot wrong w/ this code.但是这段代码有很多错误。 Your useEffect has a lot of dependencies that you're not declaring.您的 useEffect 有很多您没有声明的依赖项。

What I'd do is move detectLink to inside the effect, and have it run whenever window.location.pathname has changed.我要做的是将 detectLink 移动到效果内部,并在window.location.pathname发生更改时运行它。 Then change your onClick to deal with the routing (wherever that code is, since it isn't in this example)然后更改您的 onClick 以处理路由(无论该代码在哪里,因为它不在此示例中)

ETA:预计到达时间:

useEffect(() => {

    const detectLink = () => {
        const path = window.location.pathname
        if (path == '/') {
            setState((current) => ({
                ...current,
                home: true,
                cat: false,
                checkout: false,
            }))
            return
        }
        if (path.includes('cat')) {
            setState((current) => ({
                ...current,
                home: false,
                cat: true,
                checkout: false,
            }))
            return
        }
        if (path.includes('checkout')) {
            setState((current) => ({
                ...current,
                home: false,
                cat: false,
                checkout: true,
            }))
            return
        }
    }

    detectLink()
}, [window.location.pathname])

Then remove your click handler, since this will now run whenever the location changes since you're using Links然后删除您的点击处理程序,因为自从您使用链接以来,只要位置发生变化,它就会运行

Your problem is that you're listening for changes in pathname which isn't immediately updated after click on Link .您的问题是您正在侦听pathname的更改,单击Link后不会立即更新。 Wrap your component with withRouter and listen for changes in location.pathnamewithRouter包裹你的组件并监听location.pathname的变化

import { withRouter } from 'react-router-dom'
export const NavMenu = withRouter(({ location, history, match }) =>{
    useEffect(() => detectLink(), [location])
})

And inside detectLinkdetectLink里面

const detectLink = () => {
    const path = location.pathname
    if (path == '/') {
        setState((current) => ({
            ...current,
            home: true,
            cat: false,
            checkout: false,
        }))
        return
    }
    if (path.includes('cat')) {
        setState((current) => ({
            ...current,
            home: false,
            cat: true,
            checkout: false,
        }))
        return
    }
    if (path.includes('checkout')) {
        setState((current) => ({
            ...current,
            home: false,
            cat: false,
            checkout: true,
        }))
        return
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM