javascript - 组件正在将电子邮件类型的受控输入更改为不受控

标签 javascript reactjs jsx

我有以下组件:

import React from 'react';
import PropTypes from 'prop-types';
import Button from 'material-ui/Button';
import TextField from 'material-ui/TextField';
import {FormGroup, FormControlLabel} from 'material-ui/Form';
import Checkbox from 'material-ui/Checkbox';
import StringFunc from '../utils/StringFunc';
import _Array from 'lodash/array';
import _Collection from 'lodash/collection';

class SignUp extends React.Component {

  state = {
    oSignUp: {
      sName: '',
      sEmail: '',
      sEmailConf: '',
      sPw: '',
      bCondition: false,
    },
    bSubmit: true,
  };

  static propTypes = {
    bFluid: PropTypes.bool.isRequired,
    fHandleSignUp: PropTypes.func.isRequired
  };

  handleOnSubmit = event => {
    event.preventDefault();
    this.props.fHandleSignUp(this.state.oSignUp);
  };

  handleOnChange = name => event => {
    this.setState({
      oSignUp: {
        [name]: event.target.value
      },
    }, () => {
      this.setState({bSubmit: this.areDataFulFilled(this.state.oSignUp)})
    });

  };

  handleOnCheck = name => (event, checked) => {
    this.setState({
      [name]: checked
    }, () => this.setState({bSubmit: this.areDataFulFilled(this.state.oSignUp)}));
  };

  areDataFulFilled = state => {
    const bFulFilled = _Array.concat(StringFunc.isEmpty(state.sName),
      StringFunc.isEmpty(state.sEmail),
      StringFunc.isEmpty(state.sEmailConf),
      StringFunc.isEmpty(state.sPw),
      !state.bCondition);

    return _Collection.reduceRight(bFulFilled, (a, b) => {
      return a || b
    }, false);
  };

  render() {
    return (
      <form noValidate autoComplete='off' onSubmit={this.handleOnSubmit}>
        <TextField
          id="name"
          label="Name"
          type="text"
          fullWidth={this.props.bFluid}
          value={this.state.oSignUp.sName}
          onChange={this.handleOnChange("sName")}
          margin="normal"
        />
        <TextField
          id="email"
          label="Email"
          type="email"
          fullWidth={this.props.bFluid}
          value={this.state.oSignUp.sEmail}
          onChange={this.handleOnChange("sEmail")}
          margin="normal"
        />
        <TextField
          id="emailconf"
          label="Email confirmation"
          type="email"
          fullWidth={this.props.bFluid}
          value={this.state.oSignUp.sEmailConf}
          onChange={this.handleOnChange("sEmailConf")}
          margin="normal"
        />
        <TextField
          id="password"
          label="Password"
          type="password"
          fullWidth={this.props.bFluid}
          value={this.state.oSignUp.sPw}
          onChange={this.handleOnChange("sPw")}
          margin="normal"
        />
        <FormGroup>
          <FormControlLabel
            control={
              <Checkbox
                checked={this.state.oSignUp.bCondition}
                onChange={this.handleOnCheck("bCondition")}
                color='primary'
              />
            }
            label='I agree to terms'
          />
        </FormGroup>

        <Button type='submit'
                disabled={this.state.bSubmit}
                variant='raised'
                color='primary'
                fullWidth={this.props.bFluid}>
          Sign Up
        </Button>
      </form>
    )
  }
}

export default SignUp;

它看起来如下: enter image description here

如您所见,输入字母后,会抛出错误。
我做错了什么?

最佳答案

问题是,在状态更新期间,您将从 oSignUp 对象中删除所有键,因此更新后 oSignUp 将只有一个键(您正在更新的输入字段的键)。

解决方案:

在更新一个键时,您还必须提及所有其他键值对。使用这个:

 handleOnChange = name => event => {
    let value = event.target.value;

    this.setState(prevState => ({
      oSignUp: {

        ...prevState.oSignUp,         // =====> added this line

        [name]: value
      },
    }), () => {
      this.setState({bSubmit: this.areDataFulFilled(this.state.oSignUp)})
    });
};

检查这个片段,你会得到更好的想法:

let data = {
  obj: {
     a: 1,
     b: 2,
  },
  temp: 'hello'
};

let newData = {
  ...data,
  // only a will be available in newdata to get all use ...obj also
  obj: {
    a: 2
  }
};

console.log('newData', newData);

关于javascript - 组件正在将电子邮件类型的受控输入更改为不受控,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49410354/

相关文章:

javascript - 如何正确处理 Express 中的错误?

javascript - 没有/#/无法重新加载 React 页面

reactjs - 如何在react js中将状态值传递给formik中的初始值

javascript - 使_children在数据树中不可选择-Tabulator React

javascript - AngularJS:指令之间的通信

javascript - 单击 <a href ="#"/> 时,IE 总是重新加载整个页面

javascript - 如何从文本渲染react-router Link组件?

javascript - 修改组件的状态然后调用 "setState(this.state)"是一种好习惯吗?

javascript - 如何向 React/MUI 自动完成组件添加唯一键?

javascript - document.forms[0].submit() 有什么问题?