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

Posted

技术标签:

【中文标题】如何在嵌套函数中在无状态函数中设置状态?【英文标题】:How Can I set State in stateless Function, in a nested Function? 【发布时间】:2021-02-12 07:43:29 【问题描述】:

我知道当函数嵌套时我无法更改无状态函数中的状态,尽管我距离设置状态只有这么远才能让页面按我的意愿工作。我想把它作为一个功能组件。下面的问题是我想在这个函数下设置语言,或者我知道如何使用 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;

【问题讨论】:

【参考方案1】:

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

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

此外,您不需要 changeTounge.bind.this 进行功能性反应:D。一般来说,如果你在函数式反应中使用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;
    

【讨论】:

天哪,这太简单了。是的,需要多练习!这就是我要找的!谢谢!【参考方案2】:

可能有更简洁的方法可以做到这一点,但这似乎有效:

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;

【讨论】:

以上是关于如何在嵌套函数中在无状态函数中设置状态?的主要内容,如果未能解决你的问题,请参考以下文章

如何在嵌套对象中设置状态

使用嵌套状态作为ui-router中的选项卡

ReactJS中从父组件调用子函数时如何在子组件中设置状态

如何从我的嵌套函数中获取 Geolocation API 坐标并进入 React 状态?

React:在 setState 中设置数组对象

有没有办法将状态信息从反应钩子传递到反应中的嵌套函数?