简体   繁体   English

如何在按钮点击反应时再次调用useEffect?

[英]How to call useEffect again on button click in react?

I am beginner in react.我是反应的初学者。 I am making a small project.我正在做一个小项目。 How to add Product in cart and I am stuck at re Rendering useEffect.如何在购物车中添加产品,我被困在重新渲染 useEffect 中。 so what I want is to re Render the useEffect on button click.所以我想要的是在按钮单击时重新渲染 useEffect 。 how do I do that?我怎么做?

Here Is my Cart Component这是我的购物车组件

import React, { useContext, useEffect, useState,useCallback } from "react";
import { UserContext } from "./Context";
import { useHistory } from "react-router";
import cartImage from "../assets/man-shopping.png";
import Axios from "axios";

const Cart = () => {
  const { user, serUser } = useContext(UserContext);
  const history = useHistory();
  const [product, setProduct] = useState([]);

  const removeFromCart = (item) => {
    Axios.delete(`http://localhost:3002/cart/${item.Id}`).then((res) => {
      setProduct(
        product.filter((item) => {
          return item.Id !== res.data.Id;
        })
      );
    });
  };

  useEffect(() => {
    Axios.get(`http://localhost:3002/cart/${user.Id}`).then((res) => {
      setProduct(res.data);
    });
  }, [user]);


  return (
    <div
      className="d-flex align-items-center justify-content-center"
      style={{ height: "90vh" }}
    >
      {user.role === undefined ? (
        <div>
          <button
            className="btn btn-lg btn-primary bg-green"
            onClick={() => {
              history.push("/login");
            }}
          >
            Please Login
          </button>
        </div>
      ) : (
        <div>
          {product.length === 0 ? (
            <figure className="figure">
              <img
                src={cartImage}
                alt="cart"
                style={{ width: "100px", height: "100px" }}
              />
              <figcaption className="figure-caption text-xs-right">
                No Product Added
              </figcaption>
            </figure>
          ) : (
            <div className="d-flex">
              {product.map((item) => {
                return (
                  <div className="card">
                    <img
                      src={new Buffer.from(item.pimg).toString("ascii")}
                      className="img-fluid crd-img"
                    />
                    <div className="card-body">
                      <h5 className="card-title">{item.pname}</h5>
                      <p className="card-text">{item.pprice}</p>
                      <button
                        className="btn btn-primary"
                        onClick={() => removeFromCart(item)}
                      >
                        Remove
                      </button>
                    </div>
                  </div>
                );
              })}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

export default Cart;

so I made the removeFromCart function as useEffect dependency so it works fine but its calls the backend again and again.所以我将removeFromCart function 作为 useEffect 依赖项,所以它工作正常,但它一次又一次地调用后端。

 const removeFromCart = (item) => {
    Axios.delete(`http://localhost:3002/cart/${item.Id}`).then((res) => {
      setProduct(
        product.filter((item) => {
          return item.Id !== res.data.Id;
        })
      );
    });
  };

  useEffect(() => {
    Axios.get(`http://localhost:3002/cart/${user.Id}`).then((res) => {
      setProduct(res.data);
    });
  }, [user,removeFromCart]);

Is there any other way to re render useEffect有没有其他方法可以重新渲染 useEffect

What you need is not useEffect.你需要的不是useEffect。 Use a ' state ' to store the items and add or delete items using setState when 'state' gets updated react will automatically re-render.使用“ state ”来存储项目,并在“状态”更新时使用 setState 添加或删除项目反应将自动重新渲染。 And you can use the updated state to save in your database.您可以使用更新后的 state 保存在您的数据库中。 Also update state before calling axios在调用 axios 之前还要更新 state

Put axios.get in a function.将 axios.get 放入 function 中。

const getProduct = useCallback(() => {
    Axios.get(`http://localhost:3002/cart/${user.Id}`).then((res) => {
        setProduct(res.data);
    });
}, [user]);

const removeFromCart = (item) => {
    Axios.delete(`http://localhost:3002/cart/${item.Id}`).then((res) => {
        getProduct();
    });
};

useEffect(() => {
    getProduct();
}, [getProduct]);

You can add a boolean state like this:您可以像这样添加 boolean state:

const [isClicked, setIsCliked] = useState(false);

And toogle the boolean value whenever the button is clicked并在单击按钮时调整 boolean 值

 const removeFromCart = (item) => {
    Axios.delete(`http://localhost:3002/cart/${item.Id}`).then((res) => {
      setProduct(
        product.filter((item) => {
          return item.Id !== res.data.Id;
        })
      );
      setIsCliked(bool => !bool)
    });
  };

And your useEffect may now look like this:你的 useEffect 现在可能看起来像这样:

      useEffect(() => {
    Axios.get(`http://localhost:3002/cart/${user.Id}`).then((res) => {
      setProduct(res.data);
    });
  }, [user.id,isClicked]);

There must be a better way but this should work必须有更好的方法,但这应该有效

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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