如何在无状态函数,嵌套函数中设置状态?

时间:2020-10-29 19:52:27

标签: reactjs state react-functional-component

我知道当函数嵌套时,我无法更改无状态函数的状态,尽管我离设置状态只有很远的距离,以便按需要进行页面工作。我想将其保留为功能组件。问题在下面,我想在此功能下设置语言,或者通过其他任何可行的方法,我都知道如何对Class组件执行此操作,尽管除非获得10票,否则我宁愿选择使用功能。

  function changeTounge(e) {
  console.log("Write something!!");
  console.log(e.currentTarget.dataset.id);
  console.log(e.currentTarget.dataset.value);
  //setLanguage({ iso2: "lv", speak: "Latviešu" });
}

完整的代码是:

import React, { useState } from "react";
import { Link } from "react-router-dom";

export function PrimaryNav() {
  const [language, setLanguage] = useState({ iso2: "us", speak: "English" });
  return (
    <div className="primary-nav">
      <ul className="navigation">
        <li className="active">
          <Link to="/">Home</Link>
        </li>
        <li className="has-child">
          <a href="#nav-homepages">Opportunities</a>
          <div className="wrapper">
            <div id="nav-homepages" className="nav-wrapper">
              <ul>
                {OpsOption("RealEstate", "Real Estate")}
                {OpsOption("Vehicles", "Vehicles")}
                {OpsOption("JobSearch", "Job Search")}
                {OpsOption("PersonalCompany", "Personal Company")}
                {OpsOption("Inves`enter code here`tInIdea", "Invest In Idea")}
              </ul>
            </div>
          </div>
        </li>
        <li>
          <Link to="/contact">Help &amp; Support</Link>
        </li>

        <li className="has-child language">
          {ActiveLanguage(language.iso2, language.speak)}
          <div className="wrapper">
            <div id="nav-languages" className="nav-wrapper">
              <ul>
                {LanguageOption("English", "us")}
                {LanguageOption("British", "gb")}
                {LanguageOption("Latviešu", "lv")}
                {LanguageOption("Estonia", "ee")}
                {LanguageOption("Lithuania", "lt")}
                {LanguageOption("Russian", "ru")}
                {LanguageOption("Deutch", "de")}
                {LanguageOption("French", "fr")}
              </ul>
            </div>
          </div>
        </li>
      </ul>
    </div>
  );
}

function LanguageOption(label, classLabel) {
  return (
    <li
      onClick={changeTounge.bind(this)}
      data-id={label}
      data-value={classLabel}
    >
      <Link to="#nav-locations">
        <span className={"flag-icon flag-icon-" + classLabel}></span>
        {"  "}
        {label}
      </Link>
    </li>
  );
}

function changeTounge(e) {
  console.log("Write something!!");
  console.log(e.currentTarget.dataset.id);
  console.log(e.currentTarget.dataset.value);
  //setLanguage({ iso2: "lv", speak: "Latviešu" });
}

function OpsOption(pageLink, label) {
  return (
    <li>
      <Link to={"/" + pageLink}>{label}</Link>
    </li>
  );
}

function ActiveLanguage(iso2, activeLanguage) {
  return (
    <a href="#nav-languages">
      <span className={"flag-icon flag-icon-" + iso2}></span> {activeLanguage}
    </a>
  );
}

export default PrimaryNav;

2 个答案:

答案 0 :(得分:0)

尝试将组件嵌套在主要组件内部,它们将能够访问并设置其状态。这里仍然是一种功能模式。

另一种选择是向您的子组件添加一个道具,并通过该道具传入setLanguage函数。

此外,在功能react:D中,您不需要changeTounge.bind.this。通常,如果您在功能性反应中完全使用this,那是一个危险信号。

import React, { useState } from "react";
import { Link } from "react-router-dom";

const PrimaryNav = () => {
  const [language, setLanguage] = useState({ iso2: "us", speak: "English" });
  
  const changeTounge = (e) => {
    console.log("Write something!!");
    console.log(e.currentTarget.dataset.id);
    console.log(e.currentTarget.dataset.value);
    setLanguage({ iso2: "lv", speak: "Latviešu" });
  }

  const OpsOption = (pageLink, label) => {
    return (
      <li>
        <Link to={"/" + pageLink}>{label}</Link>
      </li>
    );
  }

  const ActiveLanguage = (iso2, activeLanguage) => {
    return (
      <a href="#nav-languages">
        <span className={"flag-icon flag-icon-" + iso2}></span> {activeLanguage}
      </a>
    );
  }

  const LanguageOption = (label, classLabel) => {
    return (
      <li
        onClick={changeTounge}
        data-id={label}
        data-value={classLabel}
      >
        <Link to="#nav-locations">
          <span className={"flag-icon flag-icon-" + classLabel}></span>
          {"  "}
          {label}
        </Link>
      </li>
    );
  }
  
  return (
    <div className="primary-nav">
      <ul className="navigation">
        <li className="active">
          <Link to="/">Home</Link>
        </li>
        <li className="has-child">
          <a href="#nav-homepages">Opportunities</a>
          <div className="wrapper">
            <div id="nav-homepages" className="nav-wrapper">
              <ul>
                {OpsOption("RealEstate", "Real Estate")}
                {OpsOption("Vehicles", "Vehicles")}
                {OpsOption("JobSearch", "Job Search")}
                {OpsOption("PersonalCompany", "Personal Company")}
                {OpsOption("Inves`enter code here`tInIdea", "Invest In Idea")}
              </ul>
            </div>
          </div>
        </li>
        <li>
          <Link to="/contact">Help &amp; Support</Link>
        </li>

        <li className="has-child language">
          {ActiveLanguage(language.iso2, language.speak)}
          <div className="wrapper">
            <div id="nav-languages" className="nav-wrapper">
              <ul>
                {LanguageOption("English", "us")}
                {LanguageOption("British", "gb")}
                {LanguageOption("Latviešu", "lv")}
                {LanguageOption("Estonia", "ee")}
                {LanguageOption("Lithuania", "lt")}
                {LanguageOption("Russian", "ru")}
                {LanguageOption("Deutch", "de")}
                {LanguageOption("French", "fr")}
              </ul>
            </div>
          </div>
        </li>
      </ul>
    </div>
  );
}





export default PrimaryNav;
    

答案 1 :(得分:0)

也许有一些更整齐的方法可以做到这一点,但这似乎可行:

import React, { useState } from "react";
import { Link } from "react-router-dom";

export function PrimaryNav() {
  const [language, setLanguage] = useState({ iso2: "us", speak: "English" });
  return (
    <div className="primary-nav">
      <ul className="navigation">
        <li className="active">
          <Link to="/">Home</Link>
        </li>
        <li className="has-child">
          <a href="#nav-homepages">Opportunities</a>
          <div className="wrapper">
            <div id="nav-homepages" className="nav-wrapper">
              <ul>
                {OpsOption("RealEstate", "Real Estate")}
                {OpsOption("Vehicles", "Vehicles")}
                {OpsOption("JobSearch", "Job Search")}
                {OpsOption("PersonalCompany", "Personal Company")}
                {OpsOption("Inves`enter code here`tInIdea", "Invest In Idea")}
              </ul>
            </div>
          </div>
        </li>
        <li>
          <Link to="/contact">Help &amp; Support</Link>
        </li>

        <li className="has-child language">
          {ActiveLanguage(language.iso2, language.speak)}
          <div className="wrapper">
            <div id="nav-languages" className="nav-wrapper">
              <ul>
                {LanguageOption("English", "us", setLanguage)}
                {LanguageOption("British", "gb", setLanguage)}
                {LanguageOption("Latviešu", "lv", setLanguage)}
                {LanguageOption("Estonia", "ee", setLanguage)}
                {LanguageOption("Lithuania", "lt", setLanguage)}
                {LanguageOption("Russian", "ru", setLanguage)}
                {LanguageOption("Deutch", "de", setLanguage)}
                {LanguageOption("French", "fr", setLanguage)}
              </ul>
            </div>
          </div>
        </li>
      </ul>
    </div>
  );
}

function LanguageOption(label, classLabel, setLanguage) {
  return (
    <li
      onClick={(event) => changeTounge(event, setLanguage, label, classLabel)}
      data-id={label}
      data-value={classLabel}
    >
      <Link to="#nav-locations">
        <span className={"flag-icon flag-icon-" + classLabel}></span>
        {"  "}
        {label}
      </Link>
    </li>
  );
}

function changeTounge(e, setLanguage, label, classLabel) {
  console.log("Write something!!");
  console.log(e.currentTarget.dataset.id);
  console.log(e.currentTarget.dataset.value);
  setLanguage({ iso2: classLabel, speak: label });
}

function OpsOption(pageLink, label) {
  return (
    <li>
      <Link to={"/" + pageLink}>{label}</Link>
    </li>
  );
}

function ActiveLanguage(iso2, activeLanguage) {
  return (
    <a href="#nav-languages">
      <span className={"flag-icon flag-icon-" + iso2}></span> {activeLanguage}
    </a>
  );
}

export default PrimaryNav;