繁体   English   中英

像 ComponentDidUpdate 一样使用 useEffect

[英]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 链接复选框-选择

我所做的一些主要更改如下:

  1. 我没有为每个按钮设置单独的 state ,而是使用了一个带有 3 个键isActiveisActive2isActive3的 object 。

     const [btnStatus, setBtnStatus] = useState({ isActive: true, isActive2: true, isActive3: true });
  2. 你的处理程序现在看起来像这样。

     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); };
  3. 在你的 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM