盖茨比不会使用react挂钩来更改状态

时间:2020-02-02 19:59:36

标签: reactjs react-hooks gatsby tailwind-css

我为我的gatsby网站创建了一个组件。 我想为其编写一个简单的切换功能:

import React, { useState } from "react"
import './css/header.css'

function clicker(state) {
   console.log(state);
}

const header = () => {

const [isExpanded, toggleExpansion] = useState(false)

return (

    <div>
        <nav className="main-nav">
            <div className={'container container-wide'}>

                {/* responsive toggle */}
                <div className="block lg:hidden">
                    <button onClick={() => clicker(!isExpanded)}
                        className="flex items-center px-3 py-2 border rounded text-teal-200 border-teal-400 hover:text-white hover:border-white">
                        <svg className="fill-current h-3 w-3" viewBox="0 0 20 20"
                            xmlns="http://www.w3.org/2000/svg"><title>Menu</title>
                            <path d="M0 3h20v2H0V3zm0 6h20v2H0V9zm0 6h20v2H0v-2z" />
                        </svg>
                    </button>
                </div>

                {/* Main Menu*/}
                <div className={`${isExpanded ? `block` : `hidden`} w-full lg:flex lg:items-center lg:w-auto justify-end`}  >
                    <div className="text-sm lg:flex-grow">
                        <a href="#responsive-header"
                            className="block mt-4 lg:inline-block lg:mt-0 text-teal-lightest hover:text-white mx-6">
                            Docs
                            </a>
                        <a href="#responsive-header"
                            className="block mt-4 lg:inline-block lg:mt-0 text-teal-lightest hover:text-white mx-6">
                            Examples
                            </a>
                        <a href="#responsive-header"
                            className="block mt-4 lg:inline-block lg:mt-0 text-teal-lightest hover:text-white mx-6">
                            Blog
                            </a>
                    </div>
                </div>
            </div>
        </nav>
    </div>
)

}

导出默认标题;

问题是:状态似乎在那里。 当我单击链接时,clicker(state)函数会返回, 不管初始状态是什么

但是toggleExpansion函数确实不起作用或无法触发。 或...组件无法根据新状态呈现..

我不知道。 有人可以帮忙吗?

当我使用类组件时,它可以正常工作-有人可以告诉我为什么吗?

2 个答案:

答案 0 :(得分:2)

首先,您应该按照React Docs中的建议将组件名称大写。第二件事是您应该将事件处理程序逻辑移到Header组件中,因为它属于该组件。 为了触发状态更改,请在事件处理程序中修复代码,如下面的代码所示。

从您的代码中,我还看到您可能还缺少关于React Hooks的另一个重要概念。请注意,在任何特定的渲染中,道具和状态永远保持不变,并且每个渲染都有自己的事件处理程序。您的事件处理程序仅 'see' 'close over(请参见闭包)' 为其特定的渲染。因此,控制台将事件处理程序中的状态记录下来,将始终为您提供特定渲染器的状态。对setToggleExpansion的调用仅使用更新后的状态及其自身的事件处理程序再次调用您的函数组件。

希望有帮助。

const Header = () => {

  const [isExpanded, setToggleExpansion] = useState(false)

  // event handler
  function clicker() {
   console.log(isExpanded);            // logs false for the initial render
   setToggleExpansion(prev => !prev);
   console.log(isExpanded);            // logs false for the initial render
  }

  return (
    <button onClick={clicker}
     //...
    </button>
  )
}

答案 1 :(得分:1)

首先,您的组件名称应以大写字母开头React recommended,只需将其更改为Header

第二,像这样更改切换功能:

const Header = () => {
  const [isExpanded, toggleExpansion] = useState(false)

  return (
    <button onClick={() => toggleExpansion(!isExpanded)}
     //...
    </button>
  )
}

要使用它,只需像这样使用&& logical operator

{ 
   isExpanded && ( <div> ... </div> ) 
}

Edit long-star-0ob0w