【问题标题】:How to handle input change in react?如何处理反应中的输入变化?
【发布时间】:2021-04-26 10:58:57
【问题描述】:

我正在制作一个非常简单的反应应用程序,其中包含基本细节作为输入。

我在上下文中有这些表单值。

context.js

import React, { useState } from "react";

export const FormContext = React.createContext();

export function FormProvider({ children }) {
  const [formValue, setFormValue] = useState({
    basicDetails: {
      firstName: "John",
      lastName: "Doe",
      address: {
        city: "city",
        zip: "zip"
      }
    }
  });

  return (
    <FormContext.Provider value={[formValue, setFormValue]}>
      {children}
    </FormContext.Provider>
  );
}

在基本细节组件中,我正在尝试渲染表单,

basicdetails.js

以下代码工作正常

    <label htmlFor="firstName">First Name: </label>
    <input
      type="text"
      className="form-control"
      id="firstName"
      name="firstName"
      value={basicDetails.firstName}
      onChange={(event) => handleInputChange(event)}
    />

以下代码不起作用

    <label htmlFor="lastName">City: </label>
    <input
      type="text"
      id="city"
      name="city"
      value={basicDetails.address.city}
      onChange={(event) => handleInputChange(event)}
    />

原因:

第二个给定输入位于嵌套对象下,即basicDetails.address.city

我只将 name 属性值设为 city

   basicDetails: {
      firstName: "John",
      lastName: "Doe",
      address: {
        city: "city",
        zip: "zip"
      }
    }

handleInputChange 仅涵盖父级更改。

  const handleInputChange = (event) => {
    const { name, value } = event.target;

    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
  };

要求:

请帮助我更新包含嵌套对象的表单。basicdetails.address.city .

注意:

现在我有 city 和 zip,但以后它可能会扩展,并且会添加更多的字段。所以我无法对条件检查进行硬编码。

【问题讨论】:

    标签: javascript html reactjs


    【解决方案1】:

    您可以使用此方法检查json中是否存在任何属性,或者是否应将其存储在address中:

    const handleInputChange = (event) => {
        const { name, value: val } = event.target;
        console.log("name", name, value);
        // if (name === city)
        // const updateName =
        setValue((prev) => {
          const basicDetails = {
            ...prev.basicDetails,
            ...(value.basicDetails[name] !== undefined
              ? { [name]: val }
              : { address: { ...value.basicDetails.address, [name]: val } })
          };
          return { ...prev, basicDetails };
        });
      };
    

    sandbox

    【讨论】:

    • 感谢您的回答.. 但我需要动态处理此问题.. 现在我有 cityzip 但稍后它可能会扩展并且将添加更多字段到它..所以我不能硬编码它..
    • 在您的解决方案中添加了这一点,zip 已移至父级,但它只需要在address 内。现在我在父级有两个输入,在父级有两个输入嵌套级别(地址下)..
    • 现在是动态处理的。请让我知道它是否适合您
    • 这一行是什么意思? const { name, value: val } = event.target; ?我在我的真实应用程序中遇到错误 'value' is not defined ..
    • 因为您已经有一个名为 value 的变量,我将 event.target.value 重命名为 event.target.val 以防止混淆。
    【解决方案2】:

    因为你说的原因它不起作用:它是一个嵌套对象。一种解决方案是检查输入是城市还是 zip 输入,如果是,则直接更改嵌套的 basicDetails.address 对象而不是 basicDetails 对象:

    const basicDetails = Object.keys(prev.basicDetails.address).includes(name)
      ? {
        ...prev.basicDetails,
        address: { ...prev.basicDetails.address, [name]: value }
      }
      : { ...prev.basicDetails, [name]: value };
    

    【讨论】:

    • 感谢您的回答.. 但我需要动态处理此问题.. 现在我有 cityzip 但稍后它可能会扩展并且将添加更多字段到它..所以我不能硬编码它..
    • Object.keys(prev.basicDetails.address) 应该可以工作。编辑了答案。
    【解决方案3】:

    试试这个:

        <label htmlFor="lastName">City: </label>
    <input
      type="text"
      id="city"
      name="city"
      value={basicDetails.address.city}
      onChange={(event) => handleInputChange(event,(parentPropName = "address")}
    />
    

    然后在你的 handleInputChange 中:

     const handleInputChange = (event,parentPropName ) => {
    const { name, value } = event.target;
      if(parentPropName ){
        setValue((prev) => {
      const basicDetails = { ...prev.basicDetails,[ parentPropName ]: 
          ...prev.basicDetails[parentPropName ],
           [name] : value
          };
      return { ...prev, basicDetails };
      });
      }
        else {
    setValue((prev) => {
      const basicDetails = { ...prev.basicDetails, [name]: value };
      return { ...prev, basicDetails };
    });
    };
    
     }
    

    对于其他字段只需删除 parentPropName 并且在 if 条件下它将是未定义的并且将是错误的

    【讨论】:

      猜你喜欢
      • 2017-07-16
      • 2021-07-01
      • 2019-11-15
      • 1970-01-01
      • 2021-04-16
      • 2016-02-13
      • 2020-05-11
      • 2015-06-25
      • 2020-12-02
      相关资源
      最近更新 更多