以表单数据作为对象保存在表单状态下的表单-重置不起作用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了以表单数据作为对象保存在表单状态下的表单-重置不起作用相关的知识,希望对你有一定的参考价值。

我有一个带有名称和描述字段的React Form应用程序。

表单数据使用钩子保存在本地状态对象中:

const [data,setData] = useState({name: '', description: ''})

<Form />元素创建输入并使用<Field initialValue ={data.name} />传递其值

<Field />元素内,此initialValue传递到控制输入值的状态(已更新onChange:]]]

const [value,setValue] = useState(initialValue)

但是如果我重置数据对象(请参见handleResetClick功能),则不会清除输入(即使数据对象已清除)。我在做什么错?] >>我认为更改数据将导致重新渲染并重新传递initialValue,从而重置输入。

[Codepen example here-当我输入内容时,数据对象会更新,但是当我单击清除时,输入内容不会为空。

function Form() {
    const [data, setData] = React.useState({name: '', description: ''});

    React.useEffect(() => {
        console.log(data);
    },[data]);

    const onSubmit = (e) => {
        // not relevant to example
        e.preventDefault();
        return;
    }

    const handleResetClick = () => {
        console.log('reset click');
        setData({name: '', description: ''})
    }

    const onChange = (name, value) => {
        const tmpData = data;
        tmpData[name] = value;
        setData({
            ...tmpData
        }); 
    }

    return (
        <form onSubmit={onSubmit}>
            <Field onChange={onChange} initialValue={data.name} name="name" label="Name" />
            <Field onChange={onChange} initialValue={data.description} name="description" label="Description" />
            <button type="submit" className="button is-link">Submit</button>
            <button onClick={handleResetClick} className="button is-link is-light">Clear</button>
        </form>
    )
}

function Field(props) {
    const {name, label, initialValue, onChange} = props;
    const [value, setValue] = React.useState(initialValue);

    return (
        <div>
            <div className="field">
                <label className="label">{label}</label>
                <div className="control">
                        <input
                            name={name}
                            className="input"
                            type="text"
                            value={value}
                            onChange={e => {
                                setValue(e.target.value)
                                onChange(name, e.target.value)
                            }}
                            />
                </div>
            </div>
        </div>
    )
}

class App extends React.Component {
    render() {
        return (
        <div className="container">
            <Form />
        </div>
        );
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('app')
)

我有一个带有名称和描述字段的React Form应用程序。表单数据使用Hooks保存在本地状态对象中:const [data,setData] = useState({name:'',description:``}})。

...

handleResetClick上,您更改了dataForm状态,但不影响其子级。

尝试为initialValueuseEffect更改添加监听器:

function Field(props) {
  const { name, label, initialValue, onChange } = props;
  const [value, setValue] = React.useState(initialValue);

  useEffect(() => {
    setValue(initialValue);
  }, [initialValue]);

  return ...
}

Edit Q-58579232-FormUseEffect

Field作为受控组件可能会更好(即,其状态由父组件管理,而不是保持其自己的状态)。在此示例中,我交换了value而不是initialValue,只是将其作为道具传递给了该字段。 onChange然后调用父方法并在那里更新状态(在呈现时,该状态会自动向下传递回该字段):

const { useState, useEffect } = React;

function Form() {

  const [data, setData] = React.useState({
    name: '',
    description: ''
  });
  
  useEffect(() => {
    console.log(data);
  }, [data]);
  
  const onSubmit = (e) => {
    e.preventDefault();
    return;
  }
  
  const handleResetClick = () => {
    setData({name: '', description: ''})
  }
  
  const onChange = (e) => {
    const { target: { name, value } } = e;
    setData(data => ({ ...data, [name]: value }));
  }
  
  return (
    <form onSubmit={onSubmit}>
      <Field onChange={onChange} value={data.name} name="name" label="Name" />
      <Field onChange={onChange} value={data.description} name="description" label="Description" />
      <button type="submit" className="button is-link">Submit</button>
      <button onClick={handleResetClick} className="button is-link is-light">Clear</button>
    </form>
  )
}

function Field(props) {

  const {name, label, value, onChange} = props;
  
  return (
    <div>
      <div className="field">
        <label className="label">{label}</label>
        <div className="control">
          <input
            name={name}
            className="input"
            type="text"
            value={value}
            onChange={onChange}
          />
        </div>
      </div>
    </div>
  )
}

function App() {
  return (
    <div className="container">
      <Form />
    </div>
  );
}
  
ReactDOM.render(
  <App />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"></div>
答案

handleResetClick上,您更改了dataForm状态,但不影响其子级。

另一答案

Field作为受控组件可能会更好(即,其状态由父组件管理,而不是保持其自己的状态)。在此示例中,我交换了value而不是initialValue,只是将其作为道具传递给了该字段。 onChange然后调用父方法并在那里更新状态(在呈现时,该状态会自动向下传递回该字段):

以上是关于以表单数据作为对象保存在表单状态下的表单-重置不起作用的主要内容,如果未能解决你的问题,请参考以下文章

vite,elementuiPlus重置表单无效

vue+el-form表单验证、提交及重置

表单提交后重置textarea的值

ios下表单disabled样式重置

php表单mysql更新保存数据

PHP - 密码重置表单不起作用