如何在嵌套函数中的无状态函数中设置状态?
How Can I set State in stateless Function, in a nested Function?
我知道当函数嵌套时我无法更改无状态函数中的状态,尽管我只是距离设置状态以使页面工作如我所愿。我想将其保留为功能组件。下面的问题是我想在此功能下设置语言,或者我知道如何使用 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 & 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;
尝试将组件嵌套在主组件中,它们将能够访问和设置其状态。这仍然是一个功能模式。
另一种选择是向您的子组件添加一个 prop,并通过该 prop 传入 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 & 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;
可能有更简洁的方法来执行其中的一些操作,但这似乎有效:
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 & 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;
我知道当函数嵌套时我无法更改无状态函数中的状态,尽管我只是距离设置状态以使页面工作如我所愿。我想将其保留为功能组件。下面的问题是我想在此功能下设置语言,或者我知道如何使用 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 & 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;
尝试将组件嵌套在主组件中,它们将能够访问和设置其状态。这仍然是一个功能模式。
另一种选择是向您的子组件添加一个 prop,并通过该 prop 传入 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 & 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;
可能有更简洁的方法来执行其中的一些操作,但这似乎有效:
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 & 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;