我对将React Hooks与无状态组件一起使用是不熟悉的。我通常在必须使用状态时使用有状态组件。我当前的应用程序需要只能在功能组件中使用的上下文API。我已经重写了我需要工作的大多数代码,但是其中一个错误是出现了一个错误:“错误:重新渲染太多。React限制了渲染次数,以防止无限循环。”
我要转换为功能组件的组件
class pizzas extends Component {
state ={
pizzas: [
{id:1, name: 'Chicken Curry', ingredients: 'Red onions, bell peppers, chicken, pineapple, mozzarella, tomato sauce, curry, chili peppers', price: '3100', image: chickenCurry },
{id:2, name: 'Pepperoni Fresh', ingredients: 'Pepperoni, mozzarella, green peppers, pizza sauce', price: '2700', image: pepperoniFresh },
{id:3, name: 'Chicken BBQ', ingredients: 'Chicken, red onions, corn, mozzarella, bbq sauce, tomato sauce', price: '2700', image: chickenBbq },
{id:4, name: 'Shawarma Pizza', ingredients: 'Mayonnaise & ketchup, spicy chicken, red onions, tomatoes, mozzarella', price: '3100', image: sharwarmaPizza },
{id:5, name: 'Chicken Suya', ingredients: 'Mayonnaise, spicy sauce, spicy chicken, bell peppers, red onions, suya sauce, tomato sauce, mozzarella, suya spice', price: '2700', image: chickenSuya },
{id:6, name: 'Pepperoni', ingredients: 'Pepperoni, mozzarella, tomato sauce', price: '2700', image: pepperoni },
{id:7, name: 'Beef Suya', ingredients: 'Mayonnaise, spicy sauce, spicy meatballs, bell peppers, red onions, mozzarella, suya sauce, tomato sauce, suya spice', price: '2700', image: beefSuya },
{id:8, name: 'Chicken Supreme', ingredients: 'Spicy sauce, chicken and spicy chicken, mushrooms, bell peppers, olives, red onions, mozzarella, tomato sauce', price: '3100', image: chickenSupreme },
{id:9, name: 'Sweet Chili Chicken', ingredients: 'Spicy sauce, chicken, chili pepper, mozzarella, sweet chili sauce, tomato sauce', price: '2700', image: chickenCurry },
{id:10, name: 'Spicy Mixed Pizza', ingredients: 'Spicy sauce, spicy meatballs, spicy chicken, chili pepper, corn, mozzarella, buffalo sauce, tomato sauce', price: '3100', image: spicyMixedPizza },
{id:11, name: 'Margherita', ingredients: 'Mozarella, tomato sauce', price: '2200', image: margherita },
{id:12, name: 'Super Meaty', ingredients: 'Chicken, pepperonni, sausages, mozzarella, tomato sauce', price: '3100', image: superMeaty },
{id:13, name: 'Cheesy Chicken', ingredients: 'Chicken, tomatoes, cheddar, mozzarella, cheese sauce', price: '2700', image: cheesyChicken },
{id:14, name: 'Cheeseburger Pizza', ingredients: 'Beef, tomatoes, red onions, cheddar, mozzarella, mayonnaise & ketchup, tomato sauce', price: '3100', image: cheeseBurger },
{id:15, name: 'Meaty Overload', ingredients: 'Spicy sauce, pepperonni, spicy meatballs, chicken, sausages, mozzarella, tomato sauce', price: '3400', image: meatyOverload },
{id:16, name: 'Meaty BBQ', ingredients: 'Beef, pepperonni, sausages, mozzarella, bbq sauce, tomato sauce', price: '3100', image: meatyBbq },
{id:17, name: 'Hawaiian', ingredients: 'Chicken, pineapple, mozzarella, sweet chili sauce, tomato sauce', price: '2700', image: hawaiian },
{id:18, name: 'Veggie Overload', ingredients: 'Mushrooms, bell peppers, corn, olives, red onions, tomatoes, mozzarella, tomato sauce', price: '3100', image: veggieOverload }
],
showModal: false,
selectedPizza: null,
orders: []
}
toggleModalHandler = (p)=>{
this.setState({showModal: !this.state.showModal, selectedPizza: p});
}
addToOrders = (productName, productIngredients, productPrice, productImage, p)=>{
this.setState(prevState=>({
orders: [...prevState.orders, productImage, productName, productIngredients, productPrice]
}))
}
render(){
const pizza = this.state.pizzas;
return (
<Aux>
{ this.state.showModal?
<Backdrop clicked={this.toggleModalHandler}/>: null}
{ this.state.showModal ?
<Modal
clicked={this.toggleModalHandler}
sendRequest={this.sendingRequestHandler}
ingredients={this.state.selectedPizza.ingredients}
price={this.state.selectedPizza.price}
image={this.state.selectedPizza.image}
name={this.state.selectedPizza.name}
key={this.state.pizzas.id}
addToOrders={this.addToOrders}/>: null}
<div className={styles.Pizza} id="pizza">
<h1>Pizza</h1>
<div className={styles.PizzaContainer}>
{pizza.map(p=>{
return <div>
<div className={styles.PizzaCard}>
<div className={styles.PizzaCardHeader}>
<img src={p.image} alt="pizza"/>
<h1>{p.name}</h1>
<p>{p.ingredients}</p>
</div>
<div className={styles.PizzaCardFooter}>
<h3>from ₦{p.price}</h3>
<button onClick={()=>this.toggleModalHandler(p)}>Select</button>
</div>
</div>
</div>
})}
</div>
</div>
</Aux>
)
}
}
export default pizzas;
到目前为止我所做的
const Pizzas = () => {
const [showModal, setModal] = useState(false);
const [selectedPizza, setSelectedPizza] = useState(null)
const { pizzaproducts } = useContext(ProductsContext)
const toggleModalHandler = (p) => {
setModal(true);
setSelectedPizza(p)
}
return (
<Aux>
{setModal(true) ?
<Backdrop clicked={toggleModalHandler} /> : null}
{setModal(true) ?
<Modal
clicked={toggleModalHandler}
ingredients={selectedPizza.ingredients}
price={selectedPizza.price}
image={selectedPizza.image}
name={selectedPizza.name}
/> : null}
<div className={styles.Pizza} id="pizza">
<h1>Pizza</h1>
<div className={styles.PizzaContainer}>
{pizzaproducts.map(p => {
return <div>
<div className={styles.PizzaCard}>
<div className={styles.PizzaCardHeader}>
<img src={p.image} alt="pizza" />
<h1>{p.name}</h1>
<p>{p.ingredients}</p>
</div>
<div className={styles.PizzaCardFooter}>
<h3>from ₦{p.price}</h3>
<button onClick={() => toggleModalHandler(p)}>Select</button>
</div>
</div>
</div>
})}
</div>
</div>
</Aux>
)
}
export default Pizzas;
我怎样才能最好地转换它?我猜这个错误是来自togglemodalhandler。我是钩子的新手。
答案 0 :(得分:2)
您不应在模板内部设置状态。这将触发重新渲染,然后再次触发设置状态和下一个...
尝试这样的事情:
import React, { useState, useContext } from 'react';
const Pizzas = () => {
const [showModal, setModal] = useState(false);
const [selectedPizza, setSelectedPizza] = useState(null)
const { pizzaproducts } = useContext(ProductsContext)
const toggleModalHandler = (p) => {
setModal(true);
setSelectedPizza(p)
};
return (
<Aux>
{showModal ? <Backdrop clicked={toggleModalHandler} /> : null}
{showModal ?
<Modal
clicked={toggleModalHandler}
ingredients={selectedPizza.ingredients}
price={selectedPizza.price}
image={selectedPizza.image}
name={selectedPizza.name}
/> : null}
<div className={styles.Pizza} id="pizza">
<h1>Pizza</h1>
<div className={styles.PizzaContainer}>
{pizzaproducts.map(p => {
return <div>
<div className={styles.PizzaCard}>
<div className={styles.PizzaCardHeader}>
<img src={p.image} alt="pizza" />
<h1>{p.name}</h1>
<p>{p.ingredients}</p>
</div>
<div className={styles.PizzaCardFooter}>
<h3>from ₦{p.price}</h3>
<button onClick={() => toggleModalHandler(p)}>Select</button>
</div>
</div>
</div>
})}
</div>
</div>
</Aux>
)
}
export default Pizzas;
答案 1 :(得分:2)
您有条件地尝试使用setModal(true)?
进行渲染,这是不正确的,应该为showModal?
useState返回一对值:当前状态和一个更新状态的函数。这就是为什么我们写const [showModal, setModal] = useState()
。这与类中的this.state.showModal和this.setState相似,不同之处在于它们成对出现。