将输入选择传递给另一个输入字段

Pass input selection to another input field

如何将所选选项从 React Select 组件传递到具有 onChange 函数的输入。我是否可以为 Island 输入创建一个专用的 OnChange 函数,如果我这样做,我将遇到当前 onChange 函数的问题,因为它们会发生冲突,对吗?

function onChange(e) {
        setRental(() => ({ ...rental, [e.target.name]: e.target.value }));
      }

          <div>
            <Select placeholder={" Select Island"} options={options} />
          </div>

          <div>
            <input
              onChange={onChange}
              name="Island"
              placeholder="Island"
              value={rental.Island}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>

这是完整代码

import { API, Storage } from "aws-amplify";
import { useState, useRef } from "react";
import { v4 as uuid } from "uuid";
import { useRouter } from "next/router";
import { createRental } from "../graphql/mutations";
import Select from "react-select";
import Async, { useAsync } from "react-select/async";

const initialState = {
  title: "",
  description: "",
  MaxNumberOfGuest: "",
  MaxNumberOfAdults: "",
  MaxNumberOfChildren: "",
  NumberOfBedrooms: "",
  NumberOfBaths: "",
  PricePerNight: "",
  AdditionalCosts: "",
  StreetName: "",
  Area: "",
  ZipCode: "",
  Island: "",
  lat: "",
  lon: "",
};

function CreateRental() {
  const options = [
    { value: "Tenerife", label: "Tenerife" },
    { value: "Lanzarote", label: "Lanzarote" },
    { value: "Fuerteventura", label: "Fuerteventura" },
    { value: "Gran Canaria", label: "Gran Canaria" },
  ];

  const [rental, setRental] = useState(initialState);
  const [image, setImage] = useState(null);
  const hiddenFileInput = useRef(null);
  const {
    title,
    description,
    MaxNumberOfGuest,
    MaxNumberOfAdults,
    MaxNumberOfChildren,
    NumberOfBedrooms,
    NumberOfBaths,
    PricePerNight,
    AdditionalCosts,
    StreetName,
    Area,
    ZipCode,
    Island,
    lat,
    lon,
  } = rental;
  const router = useRouter();

  function onChange(e) {
    setRental(() => ({ ...rental, [e.target.name]: e.target.value }));
  }
  function onChangeHandlerTwo(e) {
    setRental(() => ({ Island, [e.target.name]: e.target.value }));
  }
  async function createNewRental() {
    if (
      !title ||
      !description ||
      !MaxNumberOfGuest ||
      !MaxNumberOfAdults ||
      !MaxNumberOfChildren ||
      !NumberOfBedrooms ||
      !NumberOfBaths ||
      !PricePerNight ||
      !AdditionalCosts ||
      !StreetName ||
      !Area ||
      !ZipCode ||
      !Island ||
      !lat ||
      !lon
    )
      return;
    const id = uuid();
    rental.id = id;
    // If there is an image uploaded, store it in S3 and add it to the post metadata
    if (image) {
      const fileName = `${image.name}_${uuid()}`;
      rental.FeaturedImage = fileName;
      await Storage.put(fileName, image);
    }

    await API.graphql({
      query: createRental,
      variables: { input: rental },
      authMode: "AMAZON_COGNITO_USER_POOLS",
    });
    router.push(`/rentals/${id}`);
  }

  async function uploadImage() {
    hiddenFileInput.current.click();
  }
  function handleChange(e) {
    const fileUploaded = e.target.files[0];
    if (!fileUploaded) return;
    setImage(fileUploaded);
  }
  return (
    <>
      <div>
        <h1 className="text-3xl font-semibold tracking-wide mt-6">
          Create new rental
        </h1>
        <input
          onChange={onChange}
          name="title"
          placeholder="Title"
          value={rental.title}
          className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
        />
        <textarea
          onChange={onChange}
          name="description"
          placeholder="description"
          value={rental.description}
          className="border-b pb-2 text-lg my-4 focus:outline-none w-full font-light text-gray-500 placeholder-gray-500 y-2"
        />
        <div className="grid grid-cols-4">
          <div>
            <input
              onChange={onChange}
              name="MaxNumberOfGuest"
              placeholder="Maximum number of guests"
              value={rental.MaxNumberOfGuest}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="MaxNumberOfAdults"
              placeholder="Maximum number of adults"
              value={rental.MaxNumberOfAdults}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="MaxNumberOfChildren"
              placeholder="Maximum number of children"
              value={rental.MaxNumberOfChildren}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="NumberOfBedrooms"
              placeholder="Number of bedrooms"
              value={rental.NumberOfBedrooms}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="NumberOfBaths"
              placeholder="Number of baths"
              value={rental.NumberOfBaths}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="PricePerNight"
              placeholder="Price Per Night (£)"
              value={rental.PricePerNight}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="AdditionalCosts"
              placeholder="Additional Costs (£) "
              value={rental.AdditionalCosts}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
        </div>
        <h2 className="text-3xl font-semibold tracking-wide mt-6">Address</h2>
        <div className="grid grid-cols-4">
          <div>
            <input
              onChange={onChange}
              name="StreetName"
              placeholder="Street Name"
              value={rental.StreetName}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="Area"
              placeholder="Area"
              value={rental.Area}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="ZipCode"
              placeholder="Zip Code"
              value={rental.ZipCode}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <Select
              placeholder={" Select Island"}
              options={options}
              changeHandler={onChangeHandlerTwo}
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="Island"
              placeholder="Island"
              value={rental.Island}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="lat"
              placeholder="Latitude"
              value={rental.lat}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
          <div>
            <input
              onChange={onChange}
              name="lon"
              placeholder="Longitude"
              value={rental.lon}
              className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
            />
          </div>
        </div>
        <div className="mt-6">
          {image && <img src={URL.createObjectURL(image)} className="my-4" />}
          <input
            type="file"
            ref={hiddenFileInput}
            className="hidden"
            onChange={handleChange}
          />
          <button
            className="bg-purple-600 text-white font-semibold px-8 py-2 rounded-lg mr-2"
            onClick={uploadImage}
          >
            Upload Featured Image
          </button>
          <button
            type="button"
            className="mb-4 bg-blue-600 text-white font-semibold px-8 py-2 rounded-lg"
            onClick={createNewRental}
          >
            Create Rental
          </button>
        </div>
      </div>
    </>
  );
}

export default CreateRental;

根据我的理解,如果您想知道可以在单个组件中创建两个 onChange 函数,它不会像您预期的那样工作,因为您正在创建两个主体不同但名称相同的函数。您可以为组件的处理程序指定任何名称。唯一重要的是你在 JSX 中 linking 那些处理程序的位置。

      function onChangeHandlerOne(e) {
        setRental(() => ({ ...rental, [e.target.name]: e.target.value }));
      }


      function onChangeHandlerTwo(e) {
            setRental(() => ({ ...rental, [e.target.name]: e.target.value }));
      }

      <div>
        <Select placeholder={" Select Island"} options={options} changeHandler={onChangeHandlerTwo}/>
      </div>

      <div>
        <input
          onChange={onChangeHandlerOne}
          name="Island"
          placeholder="Island"
          value={rental.Island}
          className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 y-2"
        />
      </div>
  1. 在Select组件中,可以调用接收到的handler 当用户选择任何选项时通过道具。

  2. 下面是伪代码。您可以在此处 link 从父组件收到的处理程序。

    # If you want to pass the event object to your handler make
    'onChange={(event)=>props.changeHandler(event)}'
    
    const Select = (props) => {
        return(
            <Form.Control
                as="select"
                # additional attributes
                onChange={props.changeHandler}
            >
            <option value="burger">Burger</option>
            <option value="pizza">Pizza</option>
        </Form.Control>
    
    )}
    

如果我理解有误或遗漏了什么,请告诉我。

删除 React select 并使用默认 select 类型。这允许 onChange 按名称字段工作。

<select
          name="Island"
          value={rental.island}
          onChange={onChange}
          placeholder={"Select Island"}
          className="border-b pb-2 text-lg my-4 focus:outline-none font-light text-gray-500 placeholder-gray-500 "
        >
          <option value="" disabled selected hidden>
            Select Island
          </option>
          <option value="Tenerife">Tenerife</option>
          <option value="Lanzarote">Lanzarote</option>
          <option value="Fuerteventura">Fuerteventura</option>
          <option value="Gran Canaria">Gran Canaria</option>
        </select>