点击事件仅在ReactJS-Hooks中的第一次和第二次工作

问题描述

我在这里面临一个有趣的问题,不确定为什么会这样。 基本上,我已经为任何单击事件设置了触发toggleDropDown()的条件,该条件将颠倒条件isDropdownOpen(为true或false),这将有助于显示下拉菜单{isDropdownOpen ? <DropDownlist /> : false}。 / p>

我看到第一次单击后isDropdownOpen的条件变为true并且没问题,我再次单击它也更改为false也没问题,但是当我第三次单击并且以后再单击时,它仍然为false,并且我可以看到elelel保留在导航栏上,任何我做错地方的建议。谢谢

  • First中单击usericon中的navbar之后,user-DropdownOpen设置为true

    After first click user-DropdownOpenis true

  • Second和以后的任何点击之后,user-DropdownOpen`仍然为假

    enter image description here

  1. 更新的代码和当前状态为current behaviour of the application的小片段
    Nav.js组件代码的
  • Snippet
   import history from "./History";

   function Nav({ userinfo,userstatus }) {
     const [isDropdownOpen,setDropdownOpen] = useState(false);
    const toggleDropDown = (e) => {
       e.preventDefault();
        history.push("/signin");
       return (
       <nav className="header">
         <label className="logo">
           <a href="/">
             <img className="yoga-image" src={ProjectLogo} />
           </a>
         </label>
   
         <ul>
           <li>
             <a
               className="glyphicon glyphicon-shopping-cart
   "
               href="./basket"
             ></a>
           </li>
           <li>
             <a className="active" href="./signin">
               {userstatus ? (
                 <button
                   style={{ border: "none",background: "none",outline: "none" }}
                   className=" signin-icon glyphicon glyphicon-user    
                   "
                   onClick={(e) => toggleDropDown(e)}
                 ></button>
               ) : (
                 <button style={{ border: "none",outline: "none" }} onClick={(e) => toggleDropDown(e)}>
                   SIGNIN
                 </button>
               )}
             </a>
           </li>
         </ul>
         {isDropdownOpen && <DropDownlist />}
       </nav>
     );
   }



    History.js组件代码的
  • Snippet

    import { createBrowserHistory } from "history";
    
    
    export default createBrowserHistory();
    
    
  • App.js组件代码的
  • Snippet

      ```
       import Signin from "./Component/Signin";
       import history from "./History";
        return (
          <Router history={history}>
    
            <div className="App">
              <header className="header">
                <Nav userinfo={userData} userstatus={siginalready} />
              </header>..................
    
             <Switch>  // here we got switch statement contains(/,/basket,/signin) 
                 <Route
                path="/"
                exact
                render={(props) => <Home {...props} userData={userData} userstatus={siginalready} addBasketitems={addBasketitems} />}
               />
    
              <Route
                path="/basket"
                exact
                render={(props) => (
                  <Basket {...props} userData={userData} userstatus={siginalready} basketItems={basketItems} updatedBasket={updatedBasket} resetBasket={resetBasket} />
                )}
              />
              <Route
                path="/signin"
                exact
                render={(props) => <Signin {...props} buyNow={buyNow} resetBuynow={resetBuynow} userData={userData} finalBuy={finalBuy} userstatus={siginalready} />}
              />
    
          <div className="footer">
            <Footer />
          </div>
        </div>
      </Router>
    );
    
  • Signin.js组件代码的
  • Snippet


    function Signin({ userData,userstatus,finalBuy,buyNow,resetBuynow }) {
    
    
    //POST request to server...................and recieve Invoices
    
      return <div>{userstatus ? <Useraccount userinfo={userData} userstatus={userstatus} finalBuy={finalBuy} allInvoices={allInvoices} /> : <SigninOptions />}</div>;
    }
    export default Signin;

解决方法

尝试将初始状态设置为false而不是从localStorage获取它,这样一开始就将其关闭(我怀疑这可能是您的问题,因为当您将状态设置为已经在本地存储中时,您将永远不会除非存储设置为false,否则再次将false设为初始条件:

b

然后在切换功能中设置状态时,请执行以下操作:

0.000000

更改组件的状态时,必须使用以前的状态(可能不是您遇到的实际问题,这只是一个好习惯)。

然后在渲染DropDownList的函数结尾将其更改为:

  const [isDropdownOpen,setDropdownOpen] = useState(false);

这类似于“二进制运算符”,因此仅当isDropDownOpen为true时,它将呈现DropDownList,否则它将不执行任何操作。

我怀疑问题可能与您创建的initialDropDownOpen()函数有关,请查看上述更改是否可以解决此问题。

P.S。您可以一个接一个地实施更改,看看其中有哪些可以解决它:),请告诉我! :)

编辑:提升状态,移动

setDropDownOpen(prevState => return { !prevState });

进入父组件,然后向您的dropDown添加一个属性,例如将其命名为{isDropDownOpen && <DropDownList />} ,因此:

  const [isDropdownOpen,setDropdownOpen] = useState(false);

您必须包装set函数并传递包装的函数:

show

,然后在Nav组件内部使用show和切换。

,

由于标签具有事件属性而发生。当您单击它时,它尝试将附加的表单作为默认值发送,并重定向url或主域。您可以做的很简单。只是使用

e.preventDefault()

您需要更新如下的onClick和toggleDropDown函数

onClick;

            {userstatus ? (
              <button
                style={{ border: "none",background: "none",outline: "none" }}
                className=" signin-icon glyphicon glyphicon-user    "
                onClick={e => toggleDropDown(e)}
              ></button>
            ) : (
              <button
                style={{ border: "none",outline: "none" }}
                onClick={e => toggleDropDown(e)}
              >
                SIGNIN
              </button>
            )}

toggleDropDown;

const toggleDropDown = e => {
  e.preventDefault();
  setDropdownOpen(prevState => !prevState);
};

有了这些更新,它将保留在您的组件中,或者将不刷新页面,或者将不尝试再次呈现您的组件。

对于localStorage,您还可以使用useEffect来更新状态。

默认将状态定义为false / true,然后编写一个useEffect挂钩。

  useEffect(() => {
    if (localStorage.getItem("test")) {
      setDropdownOpen(localStorage.getItem("test"));
    }
  },[]);

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...