javascript - 如何使用条件渲染编写干净、可读的 ReactJS 组件?
问题描述
结果没有显示在我的窗口中。我创建了一个用于测试的全局对象:
const obj = {
onam: [
{
name: "name3",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg"
},
{
name: "name2",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg"
}
],
christmas: [
{
name: "name1",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg"
},
{
name: "name0",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg"
}
]
}
下面是我在渲染中调用的函数。
const grid = (props) => {
if (props == "All") {
const keys = Object.keys(obj);
// looping through keys
keys.forEach((key, index) => {
// looping through array in keys
for(let j = 0; j < Object.keys(obj).length; j++) {
return (
<div>
<a><img src={obj[key][j].image}>{obj[key][j].name}</img></a>
</div>
)
}
});
}
}
我知道上面的函数有一些错误,但我无法解决。我{grid("All")}
在渲染内部调用。我的目标是显示一个 div,其中包含一个带有标签的所有图像的 div。我想学习一种有条件地渲染组件的干净方法。
解决方案
Ashwin 有几个问题。
- 您的组件名称应以大写字母开头。
- 使用数组而不是 object
obj
。使用数组并循环它们比循环对象更容易。 - 不要将整个组件包装在 if 语句中。它的坏习惯。
props == "All"
是错的。props 是一个对象而不是字符串。这是没有渲染的主要原因。该 if 语句将始终返回 false。<img>
不带孩子,所以不要传入{obj[key][j].name}
img 标签。将结束 img 标签之后的那个位移动到<a>
标签中。
我正在重写您的组件并添加一些注释以帮助您学习,但是还有其他几种方法可以达到相同的结果,也许是更好的方法。这对我有用,我发现它更具可读性和更容易理解。
import React from "react"
/* An array of objects is always easier to work than objects with
multiple arrays as values. You might end up duplicating a few keys like
"festival" in this example, but it will make your life easier.
*/
const arr = [
{
festival: "oman",
name: "name3",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg",
},
{
festival: "oman",
name: "name2",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg",
},
{
festival: "christmas",
name: "name1",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg",
},
{
festival: "christmas",
name: "name0",
image: "https://resize.hswstatic.com/w_828/gif/kelp-biofuel.jpg",
},
]
/*
Always make sure your components are uppercase
De-structure your props with { propName1, propName2 }
because that way you or anybody else looking at your
component immediately can recognize what props are being
passed.
*/
const Grid = ({ whatToRender }) => {
/*
Create a custom render function inside your component if
you need to render conditionally. Its easier to work with
debug and maintain.
*/
const renderGrid = () => {
if (whatToRender === "all") { // use === over == because that will check for type equality as well.
return arr.map((item) => ( // () is equivalent to return () when looping.
/* Always pass a unique key if you are creating lists or lopping */
<div key={item.image}>
<a>
<img src={item.image} alt={item.name} />
{item.name}
</a>
</div>
))
}
if (whatToRender === "onam") {
return arr.map((item) => {
if (item.festival === "onam") {
return (
<div key={item.image}>
<a>
<img src={item.image} alt={item.name} />
{item.name}
</a>
</div>
)
}
})
}
if (whatToRender === "christmas") {
return arr.map((item) => {
if (item.festival === "christmas") {
return (
<div key={item.image}>
<a> {/* Image tags don't take children they are self-closing */}
<img src={item.image} alt={item.name} />
{item.name}
</a>
</div>
)
}
})
} // Return an empty div if none of the cases pass. So, you return valid JSX
return <div></div>
}
return renderGrid() // Finally return your custom render function
}
export default Grid
编辑
再次访问这个问题时,我意识到有更好的方法来编写它。一个更短的版本。它使用上述代码示例中定义的相同 arr。
const Grid = ({ whatToRender }) => {
const renderGrid = () => {
return arr.map((item) => {
if (item.festival === whatToRender || whatToRender === "all") {
return (
<div key={item.image}>
<a>
<img src={item.image} alt={item.name} />
{item.name}
</a>
</div>
)
}
})
}
return renderGrid()
}
export default Grid
使用哪一个?第二个版本不仅因为它更短,而且因为它可以重复使用。如果将来您添加另一个节日arr
来说复活节,您只需要更改数组和您传递的道具值。该组件将不需要更改。
推荐阅读
- matlab - 将函数传递给 intlinprog?
- mysql - 在 sql 中插入当前时间和日期而不创建 data_time
- sdn - 在 POX 控制器中制作 ARP 请求
- java - LayeredLayout 容器,作为背景,在 Codenameone 中单击时变为白色
- java - CORS 阻止我进行 API 调用
- kubernetes - 通过 daemonset 运行的 Fluentd pod 因谷歌容器引擎上的警告而终止
- java - 有没有办法查看 GSON 中的值或倒带 nextString?
- keil - Keil C51 8051 端口 0 I/O
- shell - 如何在 shell 脚本中将配置文件部分名称作为参数传递
- android - 无法构建 Kotlin 项目:无法解析所有配置文件