React i18next 引入了使用 i18n 改变 Hook 顺序的方法
我有一个可重复使用的组件,多次使用来显示不同的下拉按钮。 它使用 i18n。
这是我的代码:
import React from 'react';
import { Dropdown } from 'react-bootstrap';
import shortid from 'shortid';
import { useTranslation } from 'react-i18next';
const PropertyButton = (state, name, handle, list, i18nName) => {
if (name === "Produttore") {
console.log("aa")
}
const [ t, i18n ] = useTranslation();
return (
<Dropdown>
<Dropdown.Toggle className="choiceButton servingButton btn" key="{shortid.generate()}"
item={name} onSelect={handle}>
{t(`wine.attribute.${name}`)}
</Dropdown.Toggle>
<Dropdown.Menu className="choiceButton servingButton btn">
{ list === null || list === undefined ? <></> :
list.map(item => {
const val = item.name === undefined ? item : item.name;
return (
<Dropdown.Item key={shortid.generate()} kname={name} kvalue={val} onClick={handle}>
{ i18nName === "regionList" || i18nName === "produttore" || i18nName === "venditore" ? val : t(`wine.${i18nName}.${val}`)}
</Dropdown.Item>
)
}
)}
</Dropdown.Menu>
</Dropdown>
)
};
export default PropertyButton;
该组件被调用多次,没有错误。 我认为问题不在于组件的主体,因为它只显示一个按钮。 i18n
或我使用它的方式应该有一些奇怪的东西。
有一种情况,当 name === "Produttore"
(我添加了一个 console.log
只是为了放置一个断点),然后踩在 const [ t, i18n ] = useTranslation();
行生成挂钩错误。
顺便说一句,我使用了 const [ t, i18n ] = useTranslation(); 和 const { t } = useTranslation(); 选项,结果相同。
Warning: React has detected a change in the order of Hooks called by NickSelection. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks
************** 显示如何使用 **********************
根据要求,以下是该组件的使用方式/打电话。 每次调用 PropertyButton
都会返回一个 Dropdown
按钮,并使用传递的参数进行初始化。
所有这些都在运行(以不同的语言),但只有带有 Produttore
的那个(用 ===>>>
箭头表示)会生成错误。
const NickSelection = ({
regionList,
mainListContainsEffervescenza, mainListContainsTannicità,
prezzo, setPrezzo,
effervescenza, setEffervescenza,
acidità, setAcidità,
alcolicità, setAlcolicità,
tannicità, setTannicità,
tipologia, setTipologia,
territorio, setTerritorio,
produttore, setProduttore, producerList,
venditore, setVenditore, sellerList
}) => {
return (
{/* <Footer */}
<div className="footer_container footer_container_chat" style={{ zIndex: "6000" }}>
{PropertyButton(tipologia, "Tipologia", handlePropertyButton, allowedProductTypes, "productType")}
{PropertyButton(territorio, "Territorio", handlePropertyButton, regionList, "regionList")}
{PropertyButton(acidità, "Acidità", handlePropertyButton, wineSensations, "sensation")}
{mainListContainsEffervescenza ? PropertyButton(effervescenza, "Effervescenza", handlePropertyButton, wineSensationsWith0, "sensation") : <></>}
{PropertyButton(alcolicità, "Alcolicità", handlePropertyButton, wineSensations, "sensation")}
{mainListContainsTannicità ? PropertyButton(tannicità, "Tannicità", handlePropertyButton, wineSensationsWith0, "sensation") : <></>}
{PropertyButton(prezzo, "Prezzo", handlePropertyButton, prices, "prices")}
{ producerList.length > 1 ?
===>>> PropertyButton(produttore, "Produttore", handlePropertyButton, producerList, "produttore") : <></> }
{ sellerList.length > 1 ? PropertyButton(venditore, "Venditore", handlePropertyButton, sellerList, "venditore") : <></>}
</div>
};
export default NickSelection;
I have a reusable component used many times to display different dropdown buttons.
It uses i18n.
Here is my code:
import React from 'react';
import { Dropdown } from 'react-bootstrap';
import shortid from 'shortid';
import { useTranslation } from 'react-i18next';
const PropertyButton = (state, name, handle, list, i18nName) => {
if (name === "Produttore") {
console.log("aa")
}
const [ t, i18n ] = useTranslation();
return (
<Dropdown>
<Dropdown.Toggle className="choiceButton servingButton btn" key="{shortid.generate()}"
item={name} onSelect={handle}>
{t(`wine.attribute.${name}`)}
</Dropdown.Toggle>
<Dropdown.Menu className="choiceButton servingButton btn">
{ list === null || list === undefined ? <></> :
list.map(item => {
const val = item.name === undefined ? item : item.name;
return (
<Dropdown.Item key={shortid.generate()} kname={name} kvalue={val} onClick={handle}>
{ i18nName === "regionList" || i18nName === "produttore" || i18nName === "venditore" ? val : t(`wine.${i18nName}.${val}`)}
</Dropdown.Item>
)
}
)}
</Dropdown.Menu>
</Dropdown>
)
};
export default PropertyButton;
The component is called several times, with no error.
I don't think the problem is in the body of the component, because it only shows a button. There should be something weird in i18n
or in the way I used it.
There is a case, when name === "Produttore"
(and I added a console.log
just to put a breakpoint), then stepping on the const [ t, i18n ] = useTranslation();
line generates an hook error.
BTW, I used both const [ t, i18n ] = useTranslation();
and const { t } = useTranslation();
options with the identical outcome.
Warning: React has detected a change in the order of Hooks called by NickSelection. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks
************* SHOWING HOW IT IS USED **********************
As requested, here is how the Component is used/called.
Each call to a PropertyButton
returns a Dropdown
button, initialized with the passed parameters.
All of them are running (in different languages) but only the one with Produttore
(signaled with the ===>>>
arrow) generate the error.
const NickSelection = ({
regionList,
mainListContainsEffervescenza, mainListContainsTannicità,
prezzo, setPrezzo,
effervescenza, setEffervescenza,
acidità, setAcidità,
alcolicità, setAlcolicità,
tannicità, setTannicità,
tipologia, setTipologia,
territorio, setTerritorio,
produttore, setProduttore, producerList,
venditore, setVenditore, sellerList
}) => {
return (
{/* <Footer */}
<div className="footer_container footer_container_chat" style={{ zIndex: "6000" }}>
{PropertyButton(tipologia, "Tipologia", handlePropertyButton, allowedProductTypes, "productType")}
{PropertyButton(territorio, "Territorio", handlePropertyButton, regionList, "regionList")}
{PropertyButton(acidità, "Acidità", handlePropertyButton, wineSensations, "sensation")}
{mainListContainsEffervescenza ? PropertyButton(effervescenza, "Effervescenza", handlePropertyButton, wineSensationsWith0, "sensation") : <></>}
{PropertyButton(alcolicità, "Alcolicità", handlePropertyButton, wineSensations, "sensation")}
{mainListContainsTannicità ? PropertyButton(tannicità, "Tannicità", handlePropertyButton, wineSensationsWith0, "sensation") : <></>}
{PropertyButton(prezzo, "Prezzo", handlePropertyButton, prices, "prices")}
{ producerList.length > 1 ?
===>>> PropertyButton(produttore, "Produttore", handlePropertyButton, producerList, "produttore") : <></> }
{ sellerList.length > 1 ? PropertyButton(venditore, "Venditore", handlePropertyButton, sellerList, "venditore") : <></>}
</div>
};
export default NickSelection;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
问题
您已经声明了一个常规 Javascript 函数
PropertyButton
并直接在代码中调用它。最终,您有条件地调用此函数,因此,调用的钩子的顺序发生了变化。这违反了 Hooks 规则。
解决方案
尝试将
PropertyButton
转换为 React 组件,呈现为 JSX。...
Issue
You've declared a regular Javascript function,
PropertyButton
and invoke it directly in your code. Eventually you are conditionally calling this function, and thus, the order of hooks called has changed.This is a violation of the Rules of Hooks.
Solution
Try converting
PropertyButton
into a React component, rendered as JSX....