我有一个编辑组件,应该用于我的数据库中的三个表.不过,我已经快到React Hook is called conditionally岁了.我想要条件挂钩,因为要更新的表需要根据我正在编辑的数据进行更改.似乎唯一的 Select 是:像我下面那样做,这会给钩子带来错误,或者将它拆分成三个独立的组件,这不利于创建可重用的Reaction组件.这有可能做到吗?

import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom";
import PropTypes from "prop-types";
import {
  TextField,
  FormControlLabel,
  Checkbox,
  FormGroup,
  Button
} from "@mui/material";
import { 
  useAddAttractionMutation,
  useFetchAttractionQuery,
  useUpdateAttractionMutation,
  useRemoveAttractionMutation,
  useAddRestaurantMutation,
  useFetchRestaurantQuery,
  useUpdateRestaurantMutation,
  useRemoveRestaurantMutation,
  useAddShowMutation,
  useFetchShowQuery,
  useUpdateShowMutation,
  useRemoveShowMutation,
} from "../store/apis/dappApi";
import Dropdown from "./Dropdown";
import { PARK_AREAS } from "../constants";

function Edit({ type }) {
  const { id } = useParams();
  const navigate = useNavigate();
  const parks = Object.keys(PARK_AREAS);

  const [name, setName] = useState("");
  const [park, setPark] = useState(parks[0]);
  const [area, setArea] = useState(PARK_AREAS[park][0]);
  const [completed, setCompleted] = useState(false);

  let mutationVariables;

  if (type === "attractions") {
    mutationVariables = {
      addMutation: useAddAttractionMutation()[0],
      updateMutation: useUpdateAttractionMutation()[0],
      removeMutation: useRemoveAttractionMutation()[0],
      fetchData: useFetchAttractionQuery(id),
    };
  } else if (type === "restaurants") {
    mutationVariables = {
      addMutation: useAddRestaurantMutation()[0],
      updateMutation: useUpdateRestaurantMutation()[0],
      removeMutation: useRemoveRestaurantMutation()[0],
      fetchData: useFetchRestaurantQuery(id),
    };
  } else if (type === "shows") {
    mutationVariables = {
      addMutation: useAddShowMutation()[0],
      updateMutation: useUpdateShowMutation()[0],
      removeMutation: useRemoveShowMutation()[0],
      fetchData: useFetchShowQuery(id),
    };
  }
  
  const {
    addMutation,
    updateMutation,
    removeMutation,
    fetchData: { data, isLoading },
  } = mutationVariables;
  
  const handleDelete = () => {
    removeMutation(id);
    navigate(`/${type}`);
  }

  const handleUpdate = () => {
    const updateData = {
      id,
      name,
      park,
      area,
      completed,
    };

    updateMutation(updateData);
    navigate(`/${type}`);
  }

  const handleAdd = () => {
    const attractionData = {
      name,
      park,
      area,
      completed
    };

    addMutation(attractionData);
    navigate(`/${type}`);
  }

  useEffect(() => {
    if (!isLoading && id != null) {
      setPark(data.park);
      setCompleted(data.completed);
      setName(data.name);
      setArea(data.area);
    }
  }, [isLoading]);

  return isLoading ? (
    <div className="flex items-center justify-center">Loading...</div>
  ) : (
    <div>
      <FormGroup className="flex flex-col m-6 gap-4">
        <TextField label="Name" 
          value={name}
          onChange={(event) => {
            setName(event.target.value);
          }}
        />       
        <Dropdown
          options={parks}
          value={park}
          label="Park"
          setValue={setPark}
        />
        <Dropdown
          options={PARK_AREAS[park]}
          value={area}
          label="Area"
          setValue={setArea}
        />
        <FormControlLabel
          control={
            <Checkbox
              checked={completed}
              onChange={(event) => {
                setCompleted(event.target.checked);
              }}
            />
          }
          label="Completed"
        />
        <div
          className="outline rounded-lg h-80 flex justify-center align-center"
        >
          map will go here
        </div>
        {id != null ? (
          <div className="flex justify-center gap-4">            
            <Button variant="contained" onClick={handleUpdate}>
              Save
            </Button>
            <Button variant="contained" color="error" onClick={handleDelete}>
              Delete
            </Button>
          </div>
        ) : (
          <div className="flex justify-center">
            <Button variant="contained" onClick={handleAdd}>Create</Button>
          </div>
        )}
      </FormGroup>
    </div>
  );
}

export default Edit;

Edit.propTypes = {
  type: PropTypes.string.isRequired,
};

我试着移动到定制挂钩,但得到了同样的问题.

推荐答案

您不能有条件地调用Reaction挂钩.要解决此问题,您只需无条件调用所有挂钩即可.将Mutations 触发器和查询结果分配给唯一的标识符,并使用skip选项来conditionally运行查询.

const [addAttractionTrigger] = useAddAttractionMutation();
const [updateAttractionTrigger] = useUpdateAttractionMutation();
const [removeAttractionTrigger] = useRemoveAttractionMutation();
const fetchAttractionResult = useFetchAttractionQuery(
  id,
  { skip: !["restaurants", "shows"].includes(type) } // "attractions"
);

const [addRestaurantTrigger] = useAddRestaurantMutation();
const [updateRestaurantTrigger] = useUpdateRestaurantMutation();
const [removeRestaurantTrigger] = useRemoveRestaurantMutation();
const fetchRestaurantResult = useFetchRestaurantQuery(
  id,
  { skip: !["attractions", "shows"].includes(type) } // "restaurants"
);

const [addShowTrigger] = useAddShowMutation();
const [updateShowTrigger] = useUpdateShowMutation();
const [removeShowTrigger] = useRemoveShowMutation();
const fetchShowResult = useFetchShowQuery(
  id,
  { skip: !["attractions", "restaurants"].includes(type) } // "shows"
);

let mutationVariables;

if (type === "attractions") {
  mutationVariables = {
    addMutation: addAttractionTrigger,
    updateMutation: updateAttractionTrigger,
    removeMutation: removeAttractionTrigger,
    fetchData: fetchAttractionResult,
  };
} else if (type === "restaurants") {
  mutationVariables = {
    addMutation: addRestaurantTrigger,
    updateMutation: updateRestaurantTrigger,
    removeMutation: removeRestaurantTrigger,
    fetchData: fetchRestaurantResult,
  };
} else if (type === "shows") {
  mutationVariables = {
    addMutation: addShowTrigger,
    updateMutation: updateShowTrigger,
    removeMutation: removeShowTrigger,
    fetchData: fetchShowResult,
  };
}
  
const {
  addMutation,
  updateMutation,
  removeMutation,
  fetchData: { data, isLoading },
} = mutationVariables;

Javascript相关问答推荐

具有相同参数的JS类

如何在表格上拥有水平滚动条,在正文页面上拥有垂直滚动条,同时还对html表格的标题使用位置粘性?

Phaser框架-将子对象附加到Actor

从mat—country—select获取整个Country数组

我不知道为什么setwritten包装promise 不能像我预期的那样工作

Snowflake JavaScript存储过程返回成功,尽管预期失败

Regex结果包含额外的match/group,只带一个返回

无法使用单击按钮时的useState将数据从一个页面传递到另一个页面

您能在卸载程序(QtInsteller框架)上添加WizardPage吗?

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

检索相加到点的子项

为什么JPG图像不能在VITE中导入以进行react ?

未捕获的运行时错误:调度程序为空

如何在一个对象Java脚本中获取不同键的重复值?

P5.js中的分形树

是否可以在不更改组件标识的情况下换出Reaction组件定义(以维护状态/引用等)?如果是这样的话,是如何做到的呢?

Angel Auth Guard-用户只有在未登录时才能访问登录页面,只有在登录时才能访问其他页面

使用静态函数保存 node 前的钩子

如何在单击链接时设置一个JavaScript变量(以打开弹出窗口的特定部分)

观察子组件中的@Output事件emits 器?