我想从对象上的键中获取一个数组,但是当对象为空时,长度应为0。当我尝试对数组使用console.log()
时,数组的长度是正确的,但是我的代码卡在浏览器上抛出了以下错误,并停止了执行:
RangeError: invalid array length
burger/transformedIngredients<
src/components/Burger/Burger.js:8
5 | const burger = (props) => {
6 | let transformedIngredients = Object.keys(props.ingredients).map(igKey => (
7 | // eslint-disable-next-line max-len,react/no-array-index-key
> 8 | [...Array(props.ingredients[igKey])].map((_, i) => <BurgerIngredient key={igKey + i} type={igKey} />)
9 | )).reduce((arr, el) => (
10 | arr.concat(el)
11 | ), []);
这是我正在使用的代码:
const burger = (props) => {
let transformedIngredients = Object.keys(props.ingredients).map(igKey => (
// eslint-disable-next-line max-len,react/no-array-index-key
[...Array(props.ingredients[igKey])].map((_, i) => <BurgerIngredient key={igKey + i} type={igKey} />)
)).reduce((arr, el) => (
arr.concat(el)
), []);
if (transformedIngredients.length === 0) {
transformedIngredients = <p>Please add some ingredients!</p>;
}
我正在从这里经过ingredients
:
class BurgerBuilder extends Component {
state = {
ingredients: {
salad: 0,
bacon: 0,
cheese: 0,
meat: 0,
},
totalPrice: 4,
};
render() {
return (
<Fragment>
<Burger ingredients={this.state.ingredients} />
<BuildControls
ingredientAdded={this.addIngredientHandler}
ingredientRemoved={this.removeIngredientHandler}
/>
</Fragment>
);
}
答案 0 :(得分:1)
如果一种成分的值为负,则可能会发生错误,例如:
state = {
ingredients: {
salad: -1, // this will cause the error
bacon: 0,
cheese: 0,
meat: 0,
},
totalPrice: 4,
};
您可以通过确保不会在Array
构造函数中传递负数来防止这种情况,例如,如果数字为负数,则可以传递0
:
[...Array(Math.max(0, props.ingredients[igKey]))]
答案 1 :(得分:1)
我正在从相同的课程中学习到反应,并且遇到了同样的问题。在您的const INGREDIENT_PRICES中,所有对象的大小写应与在buildcontrols.js中使用的大小写相同,并且在此const控件中检查uppper并检查单词的下位原因是否与INGREDIENT_PRICES匹配,然后问题将得到解决。
答案 2 :(得分:1)
在这种情况下,我通过设置Number.parseFloat并将价格值固定在价格整数上来尝试将价格值传递给查询参数时,将错误范围缩小到了,从而消除了导致字符串化十进制的错误。
purchaseContinueHandler = () => {
const queryParams = [];
let price = Number.parseFloat(this.state.totalPrice).toFixed(2);
for (let i in this.state.ingredients) {
queryParams.push(encodeURIComponent(i) + '=' + encodeURIComponent(this.state.ingredients[i]));
}
queryParams.push('price=' + price);
const queryString = queryParams.join('&');
this.props.history.push({
pathname: '/checkout',
search: '?' + queryString
});
该错误是由价格值中的字符串小数引起的。
答案 3 :(得分:1)
我遵循同样的路线,面临同样的问题。 totalPrice
作为配料对象对象(在reducer.js文件中)的键值对包括在内,但事实并非如此,因为它是每个动作处于更新状态的单独的键值对。
修复之前-
import * as actionTypes from './actions';
const initialState = {
ingredients: {
salad: 0,
bacon: 0,
cheese: 0,
meat: 0
},
totalPrice: 4,
};
const INGREDIENT_PRICES = {
salad: 0.5,
bacon: 1.3,
cheese: 0.6,
meat: 1,
};
const reducer = (state = initialState, action) => {
switch(action.type){
case actionTypes.ADD_INGREDIENT: return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] + 1,
`totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]`
}
};
case actionTypes.REMOVE_INGREDIENT: return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] - 1,
`totalPrice: state.totalPrice - INGREDIENT_PRICES[action.ingredientName]`
}
}
default : return state;
}
};
export default reducer;
修复后-
import * as actionTypes from './actions';
const initialState = {
ingredients: {
salad: 0,
bacon: 0,
cheese: 0,
meat: 0
},
totalPrice: 4,
};
const INGREDIENT_PRICES = {
salad: 0.5,
bacon: 1.3,
cheese: 0.6,
meat: 1,
};
const reducer = (state = initialState, action) => {
switch(action.type){
case actionTypes.ADD_INGREDIENT: return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] + 1,
},
`totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]`
};
case actionTypes.REMOVE_INGREDIENT: return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] - 1,
},
`totalPrice: state.totalPrice - INGREDIENT_PRICES[action.ingredientName]`
}
default : return state;
}
};
export default reducer;
答案 4 :(得分:0)
我不太了解为什么要对键进行额外的映射并创建多维数组,但是如果要为每个键渲染一个成分,则可以将代码更改为此:
const burger = (props) => {
let transformedIngredients = Object.keys(props.ingredients).map((igKey, i) => (
<BurgerIngredient key={igKey + i} type={igKey} />
));
}
答案 5 :(得分:0)
我正在上相同的课程,并且遇到相同的错误。检查您的reducer.js文件,并将其与课程中提供的源代码进行比较。以我为例,从reducer.js传递的数组与Burger.js接收的数组不匹配。修复reducer.js文件后,该错误消失了。
修复后,我的代码如下:
const reducer = (state = initialState, action) => {
switch (action.type) {
case actionTypes.ADD_INGREDIENT:
return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] + 1
},
totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
};
case actionTypes.REMOVE_INGREDIENT:
return {
...state,
ingredients: {
...state.ingredients,
[action.ingredientName]: state.ingredients[action.ingredientName] - 1
},
totalPrice: state.totalPrice + INGREDIENT_PRICES[action.ingredientName]
};
default:
return state;
}
};
答案 6 :(得分:0)
与您的错误相同,可能是添加配料时出现错误。
通过在复制对象行中将“ []”更改为“ {}”来解决我的问题。我没有注意到我使用了[]。
答案 7 :(得分:0)
我也犯了同样的错误,将'b'和'c'改为大写 在“培根”和“奶酪”中
通过在相同情况下制作每个字符,问题得以解决:
const controls=[
{label:'salad',type:'salad'},
{label:'bacon',type:'bacon'},
{label:'cheese',type:'cheese'},
{label:'meat',type:'meat'}
];
答案 8 :(得分:0)
感谢所有花时间提供您的答案和想法的人。 我遇到了同样的问题,解决方案是将键值更改为小写,
例如下面的代码:
错误是'Price'
大写而不是'price'
小写
checkoutContinuedHandler = () => {
const queryParams = [];
for (let ing in this.state.ingredients) {
queryParams.push(encodeURIComponent(ing) + '=' + encodeURIComponent(this.state.ingredients[ing]));
}
queryParams.push('price=' + this.state.totalPrice.toFixed(2));
const queryString = queryParams.join('&');
this.props.history.push({
pathname: '/checkout',
search: '?' + queryString
});
}
答案 9 :(得分:0)
只需从 ...state.ingredients 中删除扩展运算符,它就会起作用!
答案 10 :(得分:-1)
我正在遵循同一课程,请检查您在数据库中使用的配料名称,这些名称应与BuildControls.js
中的相同,配料类型应与您在数据库中编写的名称相同。这肯定会解决您的问题。
发生此错误是由于选择了错误的名称,这就是它说无效数组长度的原因。