![](/img/trans.png)
[英]Having trouble with using UseEffect in place of componentDidMount and componentDidUpdate
[英]Using useEffect like ComponentDidUpdate
我试图有 3 个按钮,如果一个在活动的 state 中,另外 2 个将自动处于非活动状态。
if (isActive === "true") {
setActive2("false")
setActive3("false")
}
if (isActive2 === "true") {
setActive("false")
setActive3("false")
}
if (isActive3 === "true") {
setActive("false")
setActive2("false")
}
我知道这样做可能有更好的方法,这是一个蛮力选择,我愿意接受你的建议。
我曾尝试将此代码块放入 function 并在单击按钮时运行它,但这给了我以前的 state 而不是当前的 state。 所以有人建议我使用useEffect
钩子。
useEffect(() => {
if (isActive === "true") {
setActive2("false")
setActive3("false")
}
if (isActive2 === "true") {
setActive("false")
setActive3("false")
}
if (isActive3 === "true") {
setActive("false")
setActive2("false")
}
}, [isActive, isActive2, isActive3]);
然而,这给了我同样的问题,以前的 state 正在被应用。
我肯定用这个钩子做了一些非常错误的事情(我以前从未使用过它)。 我有一个包含我所有代码的代码框
仅以有效的方式修改了onChange handler
,而没有过多地接触JSX
,并且仅在您的设置上工作。 CodeSandBox 链接复选框-选择
我所做的一些主要更改如下:
我没有为每个按钮设置单独的 state ,而是使用了一个带有 3 个键isActive
、 isActive2
和isActive3
的 object 。
const [btnStatus, setBtnStatus] = useState({ isActive: true, isActive2: true, isActive3: true });
你的处理程序现在看起来像这样。
const addPizza = (e) => { setPizzaSize(e.target.name); setStartPrice(parseInt(e.target.value)); const currentActive = e.target.id; if (currentActive === "isActive") { setBtnStatus({ isActive: true, isActive2: false, isActive3: false }); console.log("1"); } if (currentActive === "isActive2") { setBtnStatus({ isActive: false, isActive2: true, isActive3: false }); console.log("2"); } if (currentActive === "isActive3") { setBtnStatus({ isActive: false, isActive2: false, isActive3: true }); console.log("3"); } console.log(btnStatus); };
在你的 JSX 中,每个按钮看起来像这样,有自己的ids
来跟踪按钮的状态。
<button name="Extra Large" className={ btnStatus.isActive3? "button btn fourth": "button btn fourthActive" } value="20" onClick={addPizza} id="isActive3" > Extra large </button>
这里是 go。 使用相同的代码可以很好地工作:)
我已经稍微更新了代码,您可以创建单独的常量并使用它们来减少代码,并且为了保持活动的 state 仅使用单个 state。
https://codesandbox.io/s/gracious-franklin-m8wkx?file=/src/CYO.js:0-4147
import React, { useState, useEffect } from "react";
import ButtonClickable from "./button";
import ButtonClickable2 from "./button2";
import { burgerSize, vegToppings, nonvegToppings } from "./const/size";
import "./index.css";
const CYO = () => {
const [pizzaSize, setPizzaSize] = useState("Choose your Pizza Size");
const [activeSize, setActiveSize] = useState(burgerSize.MEDIUM);
const [toppings, setToppings] = useState([]);
const [startPrice, setStartPrice] = useState(0);
const addPizza = (e) => {
setPizzaSize(e.target.name);
setStartPrice(parseInt(e.target.value));
};
const CheckSize = () => {
if (pizzaSize === "Choose your Pizza Size") {
alert("You must choose a pizza size");
} else if (toppings.length === 0) {
alert("Are you sure you don't want toppings?");
} else {
alert("Sorry, this isn't a real pizza place.");
}
};
const ToppingPlusMinus = (e) => {
const { value } = e.target;
const position = toppings.indexOf(value);
if (position !== -1) {
return removeTopping(value);
}
return addTopping(value);
};
const removeTopping = (value) => {
// We need to filter out the value from the array and return the expected new value
setToppings(toppings.filter((topping) => topping !== value));
//handleToggle();
};
const addTopping = (value) => {
setToppings([...toppings, value]);
// handleToggle();
};
let toppingPrice = toppings.length * 1.5;
let price = startPrice + toppingPrice;
return (
<div className="container CYO">
<h2 className="text-center white">Create your own pizza</h2>
<div className="row">
<div className="col-sm-8">
<div className="">
<img
src="./pizza.png"
className="img-fluid pizza"
alt="Pizza"
></img>
</div>
<h3 className="white">{pizzaSize}</h3>
<p className="white">
Your Toppings: <br />
<div className="col-lg-12">
{toppings
.filter((x) => x.name !== "")
.map((toppings) => (
<img
src={toppings}
alt="topping"
width="100px"
height="100px"
></img>
))}
</div>{" "}
</p>
</div>
<div className="col-sm-4">
<h3 className="white">Pizza size</h3>
{Object.values(burgerSize).map((value) => (
<button
name={value}
className={
activeSize !== value
? "button btn fourth"
: "button btn fourthActive"
}
value="10"
onClick={(event) => {
addPizza(event);
setActiveSize(value);
}}
>
{value}
</button>
))}
<br />
<h3 className="white">Toppings</h3>
<p className="white">Toppings are $1.50 each</p>
<div className="topping-wrapper">
<h4 className="white">Meats</h4>
{nonvegToppings.map(({ name, image }) => (
<ButtonClickable
onClick={(event) => {
ToppingPlusMinus(event);
}}
name={name}
value={image}
/>
))}
<h4 className="white">Veggies</h4>
{vegToppings.map(({ name, image }) => (
<ButtonClickable2
onClick={(event) => {
ToppingPlusMinus(event);
}}
name={name}
value={image}
/>
))}
</div>
</div>
<div className="pricefooter">
<p className="price">Price: ${price}</p>
</div>
<div className="pricefooter2">
<button className="checkout button btn fourth" onClick={CheckSize}>
Checkout
</button>
</div>
</div>
</div>
);
};
export default CYO;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.