reactjs - 根据状态动态地将组件添加到反应页面
问题描述
所以我正在通过 Udemy 学习反应,讲师编写了这段代码来使用状态动态呈现汉堡配料的内容。基本上,他将状态对象转换为数组并使用它来渲染内容。
import React from "react";
import classes from "./Burger.css";
import BurgerIngredient from "./BurgerIngredients/BurgerIngr";
const burger = (props) => {
const transformedIngr = Object.keys(props.ingredients).map((igKey) => {
return [...Array(props.ingredients[igKey])].map((_, i) => {
return <BurgerIngredient key={igKey + i} type={igKey} />;
});
});
return (
<div className={classes.Burger}>
<BurgerIngredient type="bread-top" />
{transformedIngr}
<BurgerIngredient type="bread-bottom" />
</div>
);
};
export default burger;
//Object.entries(props.ingredients).map((indexOne, indexTwo)
该代码似乎非常复杂,即使在多次观看同一视频后我也无法理解。我的意思是,我在网上进行了研究,发现有一种更好的方法可以使用将对象转换为数组
Object.entries(props.ingredients)
任何人都可以向我解释现有代码是否可以使用Object.entries使其更容易?或者任何其他替代方法可以做到这一点?
BurgerBuilder.js
import React, { Component } from "react";
import Aux from "../../hoc/aux";
import Burger from "../../components/Burger/Burger";
class BurgerBuilder extends Component {
state = {
ingredients: {
meat: 1,
salad: 2,
cheese: 1,
bacon: 1,
},
};
render() {
return (
<Aux>
<Burger ingredients={this.state.ingredients} />
<div>Controls</div>
</Aux>
);
}
}
导出默认 BurgerBuilder;
BurgerIngredent.js
import React, { Component } from "react";
import Classes from "./original.css";
import PropTypes from "prop-types";
class BurgerIngredients extends Component {
render() {
let ingredient = null;
switch (this.props.type) {
case "bread-bottom":
ingredient = <div className={Classes.BreadBottom}></div>;
break;
case "bread-top":
ingredient = (
<div className={Classes.BreadTop}>
<div className={Classes.Seeds1}></div>;
<div className={Classes.Seeds2}></div>;
</div>
);
break;
case "meat":
ingredient = <div className={Classes.Meat}></div>;
break;
case "salad":
ingredient = <div className={Classes.Salad}></div>;
break;
case "cheese":
ingredient = <div className={Classes.Cheese}></div>;
break;
case "bacon":
ingredient = <div className={Classes.Bacon}></div>;
break;
default:
ingredient = null;
break;
}
return ingredient;
}
}
BurgerIngredients.propTypes = {
type: PropTypes.string.isRequired,
};
export default BurgerIngredients;
谢谢你。
解决方案
谁能解释我现有的代码
让我们从这部分开始:
Object.keys(props.ingredients)
这用于将对象转换为键数组。所以它将是一个数组['meat', 'salad', 'cheese', 'bread']
。
接下来,它将映射该字符串数组以将其转换为不同的数组。决定新数组中的内容的函数是:
(igKey) => {
return [...Array(props.ingredients[igKey])].map((_, i) => {
return <BurgerIngredient key={igKey + i} type={igKey} />;
});
}
解包的第一部分是这个,其目的是创建一个正确长度的数组:
[...Array(props.ingredients[igKey])]
props.ingredients[igKey]
将获取与给定键关联的值。所以如果关键是'meat'
,那么props.ingredients[igKey]
就是1
。或者,如果键是'salad'
,则值是2
。
有了这个号码,他们接下来会打电话Array(1)
(例如)。这将创建一个正确长度的数组。但是,有一个问题。由于数组构造函数的工作方式有一个怪癖,如果您尝试调用.map
此数组,它将无法正常工作(您将无法更改值)。所以为了解决这个问题,他们接下来要做的就是制作一个数组的副本。这就是该[... ]
部分的作用。
现在我们有一个数组,它的长度等于对象中的值。最后要做的是调用 map 并创建一些组件。这就是这段代码的作用:
.map((_, i) => {
return <BurgerIngredient key={igKey + i} type={igKey} />;
});
完成所有这些后,我们就有了一个二维数组。外部数组对每种成分都有一个条目,而内部数组的分量等于成分的数量。
是否可以使用 Object.entries 使其更容易?
我认为这不会产生任何重大变化。如果您愿意,您可以替换使用Object.keys(
with Object.entries(
,但不会有太大变化。
或者任何其他替代方法可以做到这一点?
可以通过多种方式编写此代码。有些比给出的示例更具可读性,但它们几乎都具有相同的基本功能:将对象转换为数组,然后为数组的每个元素创建另一个数组长度,然后为每个内部数组创建一个组件。
这是一个带有显式 for 循环的示例,我发现它更具可读性:
const transformedIngr = [];
for (let igKey in props.ingredients) {
const components = [];
for (let i = 0; i < props.ingredients[igKey]; i++) {
components.push(<BurgerIngredient key={igKey + i} type={igKey} />);
}
transformedIngr.push(components);
}