我有一个简单的react组件的形式,我相信有一个受控的输入:

import React from 'react';

export default class MyForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = {}
    }

    render() {
        return (
            <form className="add-support-staff-form">
                <input name="name" type="text" value={this.state.name} onChange={this.onFieldChange('name').bind(this)}/>
            </form>
        )
    }

    onFieldChange(fieldName) {
        return function (event) {
            this.setState({[fieldName]: event.target.value});
        }
    }
}

export default MyForm;

当我运行我的应用程序,我得到以下警告:

警告:MyForm正在将文本类型的未受控输入更改为 控制。输入元素不应该从不受控切换到 控制(反之亦然)。决定是使用受控的还是 在组件的生命周期内不受控制的输入元素

我相信我的输入是受控的,因为它有一个值。我在想我做错了什么?

我使用的是React 15.1.0


当前回答

在我的例子中,组件正在重新呈现并抛出一个组件正在将一个不受控制的输入类型复选框更改为受控错误。事实证明,这种行为是不保持复选框复选状态为真或假的结果(有时我得到undefined)。这里是我的错误组件的样子:

import * as React from 'react';
import { WrappedFieldProps } from 'redux-form/lib/Field';

type Option = {
  value: string;
  label: string;
};

type CheckboxGroupProps = {
  name: string;
  options: Option[];
} & WrappedFieldProps;


const CheckboxGroup: React.FC<CheckboxGroupProps> = (props) => {

  const {
    name,
    input,
    options,
  } = props;

  const [value, setValue] = React.useState<string>();
  const [checked, setChecked] = React.useState<{ [name: string]: boolean }>(
    () => options.reduce((accu, option) => {
      accu[option.value] = false;
      return accu;
    }, {}),
  );

  React.useEffect(() => {
    input.onChange(value);

    if (value) {
      setChecked({
        [value]: true, // that setChecked argument is wrong, causes error
      });
    } else {
      setChecked(() => options.reduce((accu, option) => {
        accu[option.value] = false;
        return accu;
      }, {}));
    }

  }, [value]);

  return (
    <>
      {options.map(({ value, label }, index) => {
        return (
          <LabeledContainer
            key={`${value}${index}`}
          >
            <Checkbox
              name={`${name}[${index}]`}
              checked={checked[value]}
              value={value}
              onChange={(event) => {
                if (event.target.checked) {
                  setValue(value);
                } else {
                  setValue(undefined);
                }
                return true;
              }}
            />
            {label}
          </LabeledContainer>
        );
      })}
    </>
  );
};

为了解决这个问题,我把useEffect改成了这个

React.useEffect(() => {
  input.onChange(value);

  setChecked(() => options.reduce((accu, option) => {
      accu[option.value] = option.value === value;
      return accu;
    }, {}));

}, [value]);

这使得所有复选框的状态都保持为true或false,而不会陷入未定义状态,即从React切换到开发人员,反之亦然。

其他回答

在我的情况下,在设置状态时出现拼写错误,导致定义值未定义。

这是value的默认状态

const [email, setEmail] = useState(true);

我的错误是

setEmail(res?.data?.notificationSetting.is_email_notificatio);

解是-

setEmail(res?.data?.notificationSetting.is_email_notification);

最后一个char丢失了

对于使用Formik的用户,需要为表单的initialValues添加特定字段名的默认值。

请试试这段代码

import React from "react";

class MyForm extends React.Component {
    constructor(props) {
        super(props);
        this.state = { name: "" };
        this.onFieldChange = this.onFieldChange.bind(this);
    }

    onFieldChange(e) {
        this.setState({[e.target.name]: e.target.value});
    }

    render() {
        return (
            <form className="add-support-staff-form">
                <input name="name" type="text" value={this.state.name} onChange={this.onFieldChange} />
        </form>
        );
    }
}

export default MyForm;

我在type='radio'时遇到了同样的问题

<input type='radio' checked={item。电台}…/>

原因就是那件物品。例如,无线电并不总是真或假,而是真或未定义。确保它总是布尔值,问题就会消失。

<input type='radio' checked={!!电台}…/>

我也有同样的问题。 问题是当我保持状态信息空白

  const [name, setName] = useState()

我通过像这样添加空字符串来修复它

  const [name, setName] = useState('')