[英]How to write clean, readable ReactJS Components with conditional renders?
The result is not showing in my window.结果未显示在我的 window 中。 I have created a global object for testing:
我创建了一个全局 object 用于测试:
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"
}
]
}
Below is the function I am calling inside render.下面是我在渲染中调用的 function。
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>
)
}
});
}
}
I know there is some error in the above function but I cant sort it out.我知道上面的 function 有一些错误,但我无法解决。 I am calling
{grid("All")}
inside render.我在渲染中调用
{grid("All")}
。 My aim is to display a div containing a div with all images with a tag.我的目标是显示一个 div,其中包含一个带有标签的所有图像的 div。 I would like to learn a clean way of conditionally rendering my components.
我想学习一种有条件地渲染组件的干净方法。
There are several concerns here Ashwin. Ashwin 有几个问题。
obj
.obj
。 Its easier to work with arrays and loop through them than it is to loop objects.props == "All"
is just wrong. props == "All"
是错误的。 props is an object not a string. <img>
doesn't take children so don't pass {obj[key][j].name}
into the img tag. <img>
不带孩子,所以不要将{obj[key][j].name}
传递给 img 标签。 Move that bit after the closing img tag into the <a>
tag.<a>
标记中。 I'm rewriting your component with some comments to help you learn, but there are several other ways to achieve the same result, perhaps with a better approach.我正在重写您的组件并添加一些注释以帮助您学习,但是还有其他几种方法可以达到相同的结果,也许是更好的方法。 This works for me and I find it's more readable and easier to understand.
这对我有用,我发现它更具可读性和更容易理解。
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
EDIT编辑
On visiting this question again, I realized that there was a better way to write it.再次访问这个问题时,我意识到有更好的方法来编写它。 A much shorter version.
一个更短的版本。 It uses the same arr defined in the above code sample.
它使用上述代码示例中定义的相同 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
Which one to use?使用哪一个? The second version not only because it's much shorter, but also because its reusable.
第二个版本不仅因为它更短,而且因为它可以重复使用。 If in the future you add another festival to
arr
say Easter, you just need changes in the array and the prop value you are passing.如果将来您在
arr
中添加另一个节日,比如说复活节,您只需要更改数组和您传递的道具值。 The component will require no changes.该组件将不需要更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.