我有以下函式,它接受一個 React 組件陣列,并回傳相同的陣列,但key自動將 prop 傳遞給這些組件:
const keyIt = (components) => {
const keyedComponents = components.map((Component, i)=> <Component key={i}/>)
return keyedComponents
}
用法:
const Sidenav = (props)=> {
return (keyIt([
<ListItem>Home</ListItem>,
<ListItem>About</ListItem>,
<ListItem>Contact</ListItem>,
<ListItem>Downloads</ListItem>,
<ListItem>Plans</ListItem>,
]))
}
這是一個簡單的實用程式,我想創建它來自動傳遞 key prop 以忽略錯誤(僅當我知道串列的順序永遠不會改變時)。
但它不起作用,并顯示以下錯誤:
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <ForwardRef(ListItem) />. Did you accidentally export a JSX literal instead of a component?

有什么問題?我該如何解決這個問題?
uj5u.com熱心網友回復:
正如錯誤所說,<ListItem>Home</ListItem>創建一個元素,而不是一個組件,但您正試圖將它用作一個組件。(更多關于這里的元素和關于這里的組件。)
相反,要做到這一點,您必須傳遞組件和您希望它擁有的道具,然后在 中創建元素map,如下所示:
const keyIt = (components) => {
const keyedComponents = components.map(({Component, props}, i) => <Component key={i} {...props} />);
return keyedComponents;
};
const Sidenav = (props) => {
return keyIt([
{Component: ListItem, props: {children: "Home"}},
{Component: ListItem, props: {children: "About"}},
{Component: ListItem, props: {children: "Contact"}},
{Component: ListItem, props: {children: "Downloads"}},
{Component: ListItem, props: {children: "Plans"}},
]);
};
但請注意我上面的評論,key={i}通常是反模式。
您可以使用元組使其不那么冗長[component, props, children]:
const keyIt = (components) => {
const keyedComponents = components.map(([Component, props, children], i) => (
<Component key={i} {...props}>
{children}
</Component>
));
return keyedComponents;
};
const Sidenav = (props) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setCounter((c) => c 1);
}, 1000);
return () => {
clearInterval(handle);
};
}, []);
return keyIt([
[ListItem, null, "Home"],
[ListItem, null, "About"],
[ListItem, null, "Contact"],
[ListItem, null, "Downloads"],
[ListItem, null, "Plans"],
]);
};
實時示例(我在Sidenav示例中添加了狀態,只是為了表明元素在其道具更改時正確重新渲染,因為您在評論中認為不會發生):
顯示代碼片段
const { useState, useEffect } = React;
const ListItem = ({children}) => <div>{children}</div>;
const keyIt = (components) => {
const keyedComponents = components.map(({ Component, props }, i) => (
<Component key={i} {...props} />
));
return keyedComponents;
};
const Sidenav = (props) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setCounter((c) => c 1);
}, 1000);
return () => {
clearInterval(handle);
};
}, []);
return keyIt([
{ Component: ListItem, props: { children: `Home (${counter})` } },
{ Component: ListItem, props: { children: "About" } },
{ Component: ListItem, props: { children: "Contact" } },
{ Component: ListItem, props: { children: "Downloads" } },
{ Component: ListItem, props: { children: "Plans" } },
]);
};
const Example = () => {
return <Sidenav />;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
或元組版本:
顯示代碼片段
const { useState, useEffect } = React;
const ListItem = ({children}) => <div>{children}</div>;
const keyIt = (components) => {
const keyedComponents = components.map(([Component, props, children], i) => (
<Component key={i} {...props}>
{children}
</Component>
));
return keyedComponents;
};
const Sidenav = (props) => {
const [counter, setCounter] = useState(0);
useEffect(() => {
const handle = setInterval(() => {
setCounter((c) => c 1);
}, 1000);
return () => {
clearInterval(handle);
};
}, []);
return keyIt([
[ListItem, null, `Home (${counter})`],
[ListItem, null, "About"],
[ListItem, null, "Contact"],
[ListItem, null, "Downloads"],
[ListItem, null, "Plans"],
]);
};
const Example = () => {
return <Sidenav />;
};
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/514818.html
標籤:javascript反应
上一篇:未捕獲的錯誤:操作必須是使用redux/toolkit的普通物件
下一篇:反應:輸入欄位不更新文本
