首页 > 解决方案 > React 通过 Axios Mysql Query 运行两次

问题描述

我在功能性反应应用程序中遇到了我的 axios 请求的双重执行,它通过随机插入 1 或 2 行而不是总是只有 1 行到数据库中。试图将它包装在 useEffect-Hook 中......没有帮助。通过记录执行功能,它似乎只运行一次。但在 php 方面,它执行了两次。奇怪的是,我在应用程序的其他两个部分(只是不同的项目)中实现了相同的东西,并且相同的代码可以正常工作......非常感谢任何帮助!提前谢谢!

React 中的 Js 代码:

function ReservationObjectsDialogAdd() {
  const appState = useContext(StateContext)
  const appDispatch = useContext(DispatchContext)

  const [name, setName] = useState()

  const handleKeyPressAddDialog = e => {
    if (e.which == 13) {
      setReservationObject()
    }
  }

  // add new category
  async function setReservationObject() {
    try {
      // set new Category
      const response = await Axios.post("/Main.php?cmd=setReservationObject", { name })
      console.log(response.data)

      appDispatch({ type: "getReservationObjects" })
      appDispatch({ type: "setOpenAddDialog", data: false })
    } catch (e) {
      console.log(e.message)
      console.log(lang.reservationObjectAddProblem)
    }
  }

  return (
    <Dialog open={appState.openAddDialog} onClose={e => appDispatch({ type: "setOpenAddDialog", data: false })} aria-labelledby="form-dialog-title">
      <DialogTitle id="form-dialog-title">{lang.addTimeName}</DialogTitle>
      <DialogContent>
        <TextField onChange={e => setName(e.target.value)} autoFocus margin="dense" id="name" label={lang.timeName} type="text" fullWidth required={true} onKeyPress={handleKeyPressAddDialog} />
      </DialogContent>
      <DialogActions>
        <Button onClick={e => appDispatch({ type: "setOpenAddDialog", data: false })} color="primary">
          {lang.cancel}
        </Button>
        <Button onClick={setReservationObject} color="primary">
          {lang.add}
        </Button>
      </DialogActions>
    </Dialog>
  )
}

export default ReservationObjectsDialogAdd

PHP端:

case "setReservationObject":

    $conn = new DBConnection($host, $dbuser, $dbpassword, $db);
    $post = json_decode(file_get_contents('php://input'), true);
    $maxOrder = $conn->query("SELECT MAX(orderNumber) as maxorder FROM reservationObjects", [])->fetch(PDO::FETCH_ASSOC);
    $maxOrder = $maxOrder['maxorder'] + 1;
    $activeCategory = $conn->query("SELECT id FROM reservationCategories WHERE active=?", [1])->fetch(PDO::FETCH_ASSOC);
    $conn->query("INSERT INTO reservationObjects (category,name,orderNumber,visible) values(?,?,?,?)", [$activeCategory['id'], $post['name'], $maxOrder, 1]);

    break;

这里是渲染代码:

function ReservationObjects() {
  const classes = useStyles()

  const appState = useContext(StateContext)
  const appDispatch = useContext(DispatchContext)

  const [reservationObjects, setReservationObjects] = useState([])

  const [images, setImages] = useState()

  //sort categories
  function onSortEnd({ oldIndex, newIndex }) {
    let newReservationObjects = reservationObjects.map((el, i) => {
      return el
    })

    newReservationObjects = arrayMove(newReservationObjects, oldIndex, newIndex)

    setReservationObjects(newReservationObjects)

    async function sortObjects(newReservationObjects) {
      try {
        // sort Data in DB
        const response = await Axios.post("/Main.php?cmd=sortObjects", { reservationObjects: newReservationObjects })

        appDispatch({ type: "getReservationObjects" })
        appDispatch({ type: "getReservationItems" })
      } catch (e) {
        console.log(e.message)
        console.log(lang.categorySortProblem)
      }
    }
    sortObjects(newReservationObjects)
  }

  // sort events- part 1
  function handleDragEndSortObjects(event) {
    const { active, over } = event

    if (active.id !== over.id) {
      const tempReservationObjects = reservationObjects.map((el, i) => {
        return el
      })
      let oldIndex = null
      let newIndex = null
      tempReservationObjects.map((el, i) => {
        if (active.id == el.id) {
          oldIndex = i
        }
        if (over.id == el.id) {
          newIndex = i
        }
      })
      onSortEnd({ oldIndex, newIndex })
    }
  }

  function handleDragEndAssignObjects(event) {
    console.log(event)
  }

  // in Sort-Mode check if the clicked target is a interface-entity
  function shouldCancelStart(e) {
    console.log("enter should cancel")
    if (e.target.hasAttribute("isadmin")) {
      if (e.target.attributes.isadmin.value) {
        console.log("enter should cancel return false")
        return false
      }
    }
    if (e.target.hasAttribute("interface")) {
      if (e.target.attributes.interface.value) {
        console.log("enter should cancel return true")
        return true
      }
    }
  }

  // initial loading of reservation objects
  useEffect(() => {
    async function getReservationObjects() {
      try {
        const response = await Axios.post("/Main.php?cmd=getReservationObjects", { isadmin: appState.isAdmin, category: appState.activeCategoryNumber }).then(response => {
          setReservationObjects(response.data)
          appDispatch({ type: "getReservationTimes" })
        })
      } catch (e) {
        console.log(lang.reservationCategoriesProblem)
      }
    }
    getReservationObjects()
  }, [appState.getReservationObjectsTrigger])

  //initial loading of images
  useEffect(() => {
    async function loadImages() {
      try {
        const response = await Axios.post("/Main.php?cmd=getImages")
        //console.log(response.data)
        setImages(response.data)
      } catch (e) {
        console.log(e.message)
      }
    }
    loadImages()
  }, [])

  // handle mouse leave -> background Image
  function handleObjectMouseLeave(e) {
    appDispatch({ type: "setBackgroundImage", data: "" })
  }

  //handle mouse enter -> background Image
  function handleObjectMouseEnter(e) {
    if (e.target.hasAttribute("image")) {
      let image = e.target.attributes.image.value
      appDispatch({ type: "setBackgroundImage", data: image })
    }
  }

  const sensors = useSensors(
    useSensor(PointerSensor),
    useSensor(KeyboardSensor, {
      coordinateGetter: sortableKeyboardCoordinates
    })
  )

  function Draggable(props) {
    const { attributes, listeners, setNodeRef, transform, isDragging, over } = useDraggable({
      id: props.id,
      category: props.category
    })
    const style = transform
      ? {
          transform: `translate3d(${transform.x}px, ${transform.y}px, 0)`
        }
      : undefined

    return (
      <div ref={setNodeRef} className="reservationArea__reservationObjectDraggable" style={style} {...listeners} {...attributes}>
        <ReservationObject category={props.category} key={props.id} id={props.id} name={props.name} hover={appState.hoverObjectId == props.id ? "hovering" : ""} visible={props.visible} isadmin={appState.isAdmin.toString()} id={props.id} isactive={props.active} hovered={appState.reservationItems} image={props.image} onMouseEnter={handleObjectMouseEnter} onMouseLeave={handleObjectMouseLeave} />
      </div>
    )
  }

  function sortableVsDroppable() {
    if (appState.objectsSortable) {
      return (
        <DndContext sensors={sensors} collisionDetection={closestCenter} onDragEnd={handleDragEndSortObjects}>
          <SortableContext
            items={reservationObjects.map(item => {
              return item.id
            })}
            strategy={horizontalListSortingStrategy}
            className="reservationArea__reservationObjects"
          >
            <div className="reservationArea__reservationObjects">
              {reservationObjects.map((item, i) => (
                <ReservationObject key={item.id} id={item.id} name={item.name} hover={appState.hoverObjectId == item.id ? "hovering" : ""} visible={item.visible} isadmin={appState.isAdmin.toString()} id={item.id} isactive={item.active} hovered={appState.reservationItems} image={item.image} onMouseEnter={handleObjectMouseEnter} onMouseLeave={handleObjectMouseLeave} />
              ))}
            </div>
            {appState.isAdmin ? (
              <Link to="/" onClick={e => appDispatch({ type: "setOpenAddDialog", data: true })} className="reservationArea__addObject">
                <AddCircleOutlineIcon />
              </Link>
            ) : (
              ""
            )}
          </SortableContext>
        </DndContext>
      )
    } else {
      console.log("assignable")
      return (
        <>
          <div className="reservationArea__reservationObjects">
            {reservationObjects.map((item, i) => (
              <Draggable key={item.id} category={item.category} id={item.id} index={item.id} name={item.name} hover={appState.hoverObjectId == item.id ? "hovering" : ""} visible={item.visible} isadmin={appState.isAdmin.toString()} id={item.id} isactive={item.active} hovered={appState.reservationItems} image={item.image} onMouseEnter={handleObjectMouseEnter} onMouseLeave={handleObjectMouseLeave} />
            ))}
          </div>
          {appState.isAdmin ? (
            <Link to="/" onClick={e => appDispatch({ type: "setOpenAddDialog", data: true })} className="reservationArea__addObject">
              <AddCircleOutlineIcon />
            </Link>
          ) : (
            ""
          )}
        </>
      )
    }
  }

  return (
    <div className="reservationArea__reservationObjectsContainer">
      <ReservationObjectsImage />

      {sortableVsDroppable()}
      <ReservationObjectsDialogAdd />
      <ReservationObjectsDialogEdit />
      <ReservationObjectsDialogDelete />
    </div>
  )
}

export default ReservationObjects

标签: mysqlreactjsdoublerows

解决方案


终于解决了。它在 php 部分。我用我用 Axios 发送的参数替换了直接在 mysql 中获取 activeCategory。不知何故,activeCategory-fetching 导致了这种奇怪的行为,它随机执行了一次或两次插入语句。


推荐阅读