首页 > 解决方案 > reactjs中如何在onClick中依次调用两个函数。两个函数都是异步的

问题描述

如何一个接一个地调用两个函数onClick

我的代码如下:

import React from "react";

import { Modal, Button } from "react-bootstrap";

const DeleteModal = ({
  show,
  handleClose,
  deleteModalData: { type, id },
  deleteFn,
  loading,
  dishData,
  setDishData,
}) => {
  const removeIngredient = async () => {
    let restIngredients = dishData.ingredients.filter(
      (ingredient) => ingredient.ingredient_id !== id
    );

    setDishData({ ...dishData, ingredients: [...restIngredients] });
  };

  return (
    <Modal show={show} onHide={handleClose}>
      <Modal.Header closeButton>
        <Modal.Title>Delete {type}</Modal.Title>
      </Modal.Header>
      <Modal.Body>Are you sure you want to delete this {type}?</Modal.Body>
      <Modal.Footer>
        <Button variant="outline-secondary" onClick={handleClose}>
          No
        </Button>
        <Button
          variant="primary"
          onClick={() => {
            removeIngredient();
            deleteFn();
          }}
          disabled={loading}
        >
          Yes {loading ? "..." : null}
        </Button>
      </Modal.Footer>
    </Modal>
  );
};

export default DeleteModal;

在上述组件的父组件中,我定义了 props deleteFn 和 setDishData 如下:

删除Fn


  
  const deleteFn = () => {
    saveIngredients();
  };

  const filteredIngredientData = () =>
    /**
     * filteredIngredientData - filters out the fields (from ingredients object) that are required by the API
     */
    ingredients
      ?.reduce((acc, val) => {
        return [
          acc,
          {
            ingredient_quantity: val.ingredient_quantity,
            ingredient_id: val.ingredient_id,
            is_required: val.is_required,
          },
        ];
      }, [])
      .flat(Infinity);

  const [loadingSaveIngredients, setLoadingSaveIngredients] = useState(false);
  const [ingredientsUpdated, setIngredientsUpdated] = useState(false);

  const saveIngredients = () => {
    /**
     * saveIngredients - Upload ingredients with updated quantities if any
     */
    setLoadingSaveIngredients(true);
    axios({
      method: "PUT",
      url: `${BASE_URL}/dishes/${props.match.params.id}/ingredients`,
      data: { ingredients: filteredIngredientData() },
    })
      .then((res) => {
        setLoadingSaveIngredients(false);
        setShowDeleteModal(false);
        setIngredientsUpdated(true);
      })
      .catch((err) => console.log(err));
  };

setDishData

const [dishData, setDishData] = useState({});

我也尝试过使用承诺,但没有运气。有什么简单的方法可以做到这一点吗?

我知道我必须以某种方式使用异步等待,但我无法理解我应该如何使用它。任何帮助将不胜感激 :)

标签: javascriptreactjsasynchronousasync-awaitreact-hooks

解决方案


编辑:

所以我认为我执行错了;工商管理学院:

  1. 当您调用 setDishData 时,还调用 toggleRemoved 以指示它在 removeIngredients 中被调用(如果这是调用 setDishData 的唯一位置,那么您不需要实现 remove/toggleRemoved)

  2. 然后在一个 useEffect 中调用 deleteFn,其中 discData 是依赖项;由于deleteFn依赖于setDishData,而setDishData改变了dishData,所以改变完成后会触发useEffect。

  3. 在 deleteFn 中添加一个条件来检查是否删除为真(仅当还从其他函数调用 setDishData 时才需要这样做,因为您不希望这些函数在 deleteFn 函数中触发 saveIngredients i)。

const [dishData, setDishData] = useState(0);
const [removed, toggleRemoved] = useState(false);

const removeIngredients = () => {
   let restIngredients = dishData.ingredients.filter(
      (ingredient) => ingredient.ingredient_id !== id
    );

    setDishData({ ...dishData, ingredients: [...restIngredients] });
    toggleRemoved(true); 
}

useEffect(() => {
     deleteFn(); 
}, [dishData]);
<button onClick={removeIngredients}>
const deleteFn = () => {
    if(removed){
     saveIngredients();
     toggleRemoved(false); 
    }
 };

推荐阅读