开发者问题收集

React 函数参数未定义

2022-10-29
1196

我对 React 还不熟悉,正在尝试使用获取请求来更新我的 api,该请求获取我的“表单”提供的值。我试图将变量作为参数传递给函数,但它未定义。

我想这可能与它是异步有关,但我并不完全确定。

import './MakeRequest.css';
import React, { useState , useEffect } from 'react'
import { useLocation } from "react-router-dom";

const MakeRequest = () => {

    const [partySize, setPartySize] = useState(0);
    const [time, setTime] = useState("");
    const [expiration_date, setExpirationDate] = useState("");

    const addRequests = async ({restaurant,partySize,time,expiration_date}) => {
      //values are undefined expect restaurant_name
      console.log(partySize)
      console.log(time)
      console.log(expiration_date)
      let item={"restaurant":restaurant.restaurant_name,"party_size":partySize,"time": time,"expiration_date":expiration_date}
      let result = await fetch("api thingy", {
          method: 'POST',
          headers:{
              "Content-Type":"application/json",
              "Accept":'application/json'
          },
          body:JSON.stringify(item)
          })
      result = await result.json();
    };

    const location = useLocation();
    const restaurant = location.state;

    return (
    <div className = "makeRequest">
        <img src={restaurant.picture} alt="" className="requestpicture"/>
        <h1> Reservation at {restaurant.restaurant_name} </h1>
        <h2> {restaurant.address} </h2>
        <input type = "number"  placeholder = "Party Size"  id = "party-size"
        onChange = {(e)=>setPartySize(e.target.value)}
        className = "form-control"/>
        <input type = "time"  placeholder = "Time"  id = "time"
        onChange = {(e)=>setTime(e.target.value)}
        className = "form-control"/>
        <input type = "date"  placeholder = "Expiration Date"  id = "expiration-date"
        onChange = {(e)=>setExpirationDate(e.target.value)}
        className = "form-control"/>
        {/*
<button onClick={() => console.log(partySize)}> Make Request </button> 
   */}
        <button onClick={() => addRequests(restaurant,partySize,time,expiration_date)}> Make Request </button> 
    </div>
  )}
  export default MakeRequest;

我尝试检查是否由于某种原因这些值从未被设置过。但是当我运行注释掉的代码时:

<button onClick={() => console.log(partySize)}> Make Request </button> 

我实际上收到了正确的值。为什么会这样?

1个回答

您正在使用 5 个参数调用 addRequests,但您的函数需要一个对象。

您可以 从函数声明中删除花括号:

const addRequests = async (restaurant,partySize,time,expiration_date) => {

或者 将它们添加到您调用它的位置:

onClick={() => addRequests({restaurant,partySize,time,expiration_date})}

其他信息

接受许多参数的函数使用起来很烦人,因为您必须记住按什么顺序传递它们:

// args must be passed in this order
function addRequests (restaurant, partySize, time, expiration_date) { ... }

为了避免此问题,通常声明只接受单个参数的函数,即具有命名属性的对象:

function addRequests(options) {}

以这种方式声明,可以调用函数而不必考虑参数顺序:

const request = {
  partySize: 5,
  expiration_date: new Date(),
  time: '7:00',
  restaurant: {
    name: 'Pizza Chunks',
    address: '999 Chonky Chonk Way'
  }
}

addRequests(request);

然后,该函数可以根据名称提取所需的信息:

function addRequests(options) {
  const time = options.time; // '7:00'
  const partySize = options.partySize; // 5
  ...
}

它可以通过解构一次提取一堆选项。这相当于前面的代码片段:

function addRequests(options) {
  const { time, partySize } = options;
  ...
}

为了进一步收紧代码,您可以对传入的参数进行解构。该函数仍然接受单个参数。我们只是从该参数中提取属性。同样,这相当于上面的示例。

function addRequests({ time, partySize }) {
  ...
}

简写属性名称

理解调用函数时花括号的作用的另一个关键点是“简写属性名称”。声明对象文字时,您可以省略属性的“值”,只需重复名称:

const partySize = 5;
const time = '7:00';

const options = {
  partySize,
  time,
}

// same as
const options = {
  partySize: partySize,
  time: time,
}

因此,当您执行此操作时(使用花括号):

addRequests({ restaurant, partySize, time, expiration_date })

您将传递一个带有这些字段的参数,即一个对象。

如果没有花括号,您将按特定顺序传递 4 个参数:

addRequests( restaurant, partySize, time, expiration_date )

您可以使其以任何一种方式工作,但您必须决定函数是否采用多个位置参数或单个选项对象参数。

当然,如果您愿意,您可以同时执行这两项操作:

function someFunc(foo, options) { ... }

someFunc(24, { bing, bang, boom })
ray
2022-10-29