组件正在更改电子邮件类型的受控输入以使其不受控制

时间:2018-03-21 15:26:47

标签: 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;

看起来如下: querydsl 3 docs

正如您所看到的,在输入一封信之后,它会引发错误 我做错了什么?

1 个答案:

答案 0 :(得分:1)

问题是,在状态更新期间,您正在删除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);