不同表react-redux的条件api端点

问题描述 投票:0回答:1

我有一个编辑组件,应该用于我的数据库中的三个表。然而我遇到了

React Hook is called conditionally
。我想要条件挂钩,因为正在更新的表需要根据我正在编辑的数据进行更改。似乎唯一的选择是:像我下面的那样执行,这会给出钩子错误,或者将其分成三个单独的组件,这不利于制作可重用的反应组件。这可以做到吗?

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,
};

我尝试移动到自定义挂钩,但遇到了同样的问题。

reactjs redux react-hooks react-redux
1个回答
0
投票

你不能有条件地调用 React hooks。要解决这个问题,您只需无条件调用所有挂钩即可。将突变触发器和查询结果分配给唯一标识符,并使用

skip
选项有条件地 运行查询。

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;
© www.soinside.com 2019 - 2024. All rights reserved.