为什么我的反应挂钩状态仅在单击两次后更新

时间:2019-09-27 13:39:00

标签: reactjs

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>
    )
}

我的菜单看起来像这样。我想在单击菜单项时将css类active分配给该项。

问题是,一击将无法实现,我需要双击。看来状态是滞后的,似乎只有在我触发下一个动作时才会更新。

2 个答案:

答案 0 :(得分:2)

我的猜测是window.location.pathname在渲染之前没有更新。但是此代码有很多错误。您的useEffect具有许多未声明的依赖项。

我要做的是将detectLink移到效果内部,并在window.location.pathname发生更改时运行它。然后更改您的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])

然后删除您的点击处理程序,因为自从使用链接以来,该处理程序现在将在位置更改时运行。

答案 1 :(得分:1)

您的问题是您正在监听pathname中的更改,这些更改在单击Link之后不会立即更新。用withRouter包装您的组件,并听location.pathname

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

detectLink

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
    }
}