Javascript react中的对象克隆

Javascript react中的对象克隆,javascript,reactjs,object,react-context,context-api,Javascript,Reactjs,Object,React Context,Context Api,我正在制作一个简单的react应用程序,它有一些基本输入,如名字、姓氏等 输入的状态在上下文api中处理,如 context.js 在这里,为了复制上下文的初始值,我尝试了使用扩展运算符 const initialValue = { ...value }; 在handleSubmit中,函数试图获取最初复制的值,即…,initialValue,但这是记录最新更改的值 工作示例: 要求: 单击表单提交后,我需要使用初始上下文数据重置表单值 为了实现仅将值重置为初始数据,我尝试了扩展运算符{…

我正在制作一个简单的react应用程序,它有一些基本输入,如名字、姓氏等

输入的状态在上下文api中处理,如

context.js

在这里,为了复制上下文的初始值,我尝试了使用扩展运算符

  const initialValue = { ...value };
在handleSubmit中,函数试图获取最初复制的值,即…,initialValue,但这是记录最新更改的值

工作示例:

要求:

单击表单提交后,我需要使用初始上下文数据重置表单值

为了实现仅将值重置为初始数据,我尝试了扩展运算符{…value},但我认为这种方法是错误的

在这种情况下,即使是JSON.parseJSON.stringifyvalue也不起作用


请任何人帮助我实现在提交时将表单值设置为初始上下文的功能。

如果您只想将初始值始终保持为第一次值,您需要这样做

const initialValue = useMemo(() => value, []);

作为您的代码,该函数在值更改时运行,因此initialValue在值更改时每次都更改。这里的另一个答案似乎足够了。您还可以将初始字段值保存在React ref const initialValue=React.useRefvalue;然后以initialValue.current访问

实际上,您希望您的上下文对上下文状态有更多的控制。我建议创建一个重置函数,将其包含在儿童可以使用的上下文中

context.js

分解初始状态定义,提供默认上下文值,并将状态和回调传递给上下文值

const initialFormState = {
  basicDetails: {
    firstName: "",
    lastName: "",
    address: {
      city: "",
      zip: "123"
    }
  }
};

export const FormContext = React.createContext({
  formValue: initialFormState,
  setFormValue: () => {},
  reset: () => {}
});

export function FormProvider({ children }) {
  const [formValue, setFormValue] = useState(initialFormState);

  const reset = () => setFormValue(initialFormState);

  return (
    <FormContext.Provider
      value={{ value: formValue, setValue: setFormValue, reset }}
    >
      {children}
    </FormContext.Provider>
  );
}

谢谢你的回答,兄弟。。我对这个问题有一个疑问。。有没有办法在handleInputChange函数中更改这行代码{address:{…value.basicDetails.address,[name]:val}},因为有时我会有更多像address这样的对象,所以有没有办法处理而不必硬编码数据?@未定义理想情况下,您希望表单数据是平面的。但是,您的状态不是,因此在setValue函数中必然会出现从嵌套到展平的映射,或者从嵌套到展平的映射。您可以将其抽象为一个实用程序,该实用程序可以解析对象路径,可以将name=basicDetails.address.city解析为需要更新的嵌套状态。看看我的描述。好的,兄弟,谢谢你的评论,我会看的。。
const initialValue = useMemo(() => value, []);
const initialFormState = {
  basicDetails: {
    firstName: "",
    lastName: "",
    address: {
      city: "",
      zip: "123"
    }
  }
};

export const FormContext = React.createContext({
  formValue: initialFormState,
  setFormValue: () => {},
  reset: () => {}
});

export function FormProvider({ children }) {
  const [formValue, setFormValue] = useState(initialFormState);

  const reset = () => setFormValue(initialFormState);

  return (
    <FormContext.Provider
      value={{ value: formValue, setValue: setFormValue, reset }}
    >
      {children}
    </FormContext.Provider>
  );
}
const BasicDetails = () => {
  const {value, setValue, reset} = React.useContext(FormContext);
  const { basicDetails } = value;

  const handleInputChange = (event) => {
    const { name, value: val } = event.target;
    setValue((prev) => {
      const basicDetails = {
        ...prev.basicDetails,
        ...(value.basicDetails[name] !== undefined
          ? { [name]: val }
          : { address: { ...value.basicDetails.address, [name]: val } })
      };
      return { ...prev, basicDetails };
    });
  };

  const handleSubmit = (e) => {
    e.preventDefault();

    // Do what you need with the current form values
    console.log("Values", value);

    // Finally reset the form
    e.target.reset();
  };

  return (
    <div>
      <h1> Basic Details </h1>
      <form onSubmit={handleSubmit} onReset={reset}>
        <label htmlFor="firstName">First Name: </label>
        <input
          type="text"
          className="form-control"
          id="firstName"
          name="firstName"
          value={basicDetails.firstName}
          onChange={handleInputChange}
        />
        <br />
        <br />
        <label htmlFor="lastName">Last Name: </label>
        <input
          type="text"
          className="form-control"
          id="lastName"
          name="lastName"
          value={basicDetails.lastName}
          onChange={handleInputChange}
        />
        <br />
        <br />
        <label htmlFor="lastName">City: </label>
        <input
          type="text"
          id="city"
          name="city"
          value={basicDetails.address.city}
          onChange={handleInputChange}
        />
        <br />
        <br />
        <label htmlFor="lastName">Zip: </label>
        <input
          type="text"
          className="form-control"
          id="lastName"
          name="zip"
          value={basicDetails.address.zip}
          onChange={handleInputChange}
        />
        <br />
        <br />
        <button type="submit">
          Submit
        </button>
      </form>
    </div>
  );
};