在多次调用中未定义this.SetState

时间:2019-04-22 19:09:00

标签: reactjs

我在React应用程序中遇到一种情况,我需要将GET请求的响应保存到状态上的某个属性上,然后将包含该属性数据和其他表单数据的POST请求发送到服务器。

为此,我按如下所示在构造函数中定义我的属性和表单数据

constructor() {
    super()
    this.state = {
      Register: {
        Name: '',
        FatherName: '',
        Age: '',
        Gender: '',
        Telephone1: '',
        Telephone2: '',
        labelWidth: 0,
        name: '',
      },
      MR_No: '',
    }
    // console.log(cookies.get('token'));
    this.MR_No = this.MR_No.bind(this);

  }

MR_No值设置为的函数

MR_No() {

    const self = this;
    axios({
      method: 'get',
      url: 'http://ec2-xx-xxx-xxx-xxx.compute-1.amazonaws.com:3000/createmrnumber',

    })
      .then(function (json) {
        var data = json;
        console.log(json.data);
        var mr = json.data
        console.log(mr);

        self.setState({
          MR_No: mr
        })

        console.log("MR Number", self.state.MR_No);

      }).catch(error => {
        console.log(error)
      })


  }

在渲染中,我使用文本框和按钮调用该函数并显示响应

<div >

        <RecAppbar />
        <h2 style={{ color: '#2699FB' }}>Register Patient</h2>
        <div>
        <TextField
          disabled
          // id="outlined-disabled"
          label={this.state.MR_No}
          defaultValue={this.state.MR_No}
          className={classes.textField}
          margin="normal"
          variant="outlined"
        />
         <Button variant="outlined" style={{ backgroundColor: '#2699FB',marginTop:'2%' }} onClick={(event) => this.MR_No(event)}><b>Generate MR_No</b></Button>
         </div>

问题是,当我使用常规绑定操作设置状态的其他属性,然后调用此GET API设置MR_No值时,会引发错误self.setState不是函数。如果我在设置其他属性之前先设置其属性,则效果很好。我尝试使用箭头功能和其他绑定解决方案,但没有用。 如果有人能帮助我解决这个问题,我会感到很高兴。

下面是完整的代码


import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import RecAppbar from '../RecAppar'
import OutlinedInput from '@material-ui/core/OutlinedInput';
import InputLabel from '@material-ui/core/InputLabel';
import FormControl from '@material-ui/core/FormControl';
import axios from 'axios'
import Input from '@material-ui/core/Input';
import toastr from 'toastr'
import 'toastr/build/toastr.min.css'
import Cookies from 'universal-cookie';

const cookies = new Cookies();

const styles = theme => ({
  container: {
    display: 'flex',
    flexWrap: 'wrap',
  },
  textField: {
    marginLeft: theme.spacing.unit,
    marginRight: theme.spacing.unit,


  },
  dense: {
    marginTop: 16,
  },
  menu: {
    width: 200,
  },
  formControl: {
    margin: theme.spacing.unit,
    minWidth: '40',
  },
  selectEmpty: {
    marginTop: theme.spacing.unit * 2,
  },
});

class RegisterPatient extends Component {
  constructor() {
    super()
    this.state = {
      Register: {
        Name: '',
        FatherName: '',
        Age: '',
        Gender: '',
        Telephone1: '',
        Telephone2: '',
        labelWidth: 0,
        name: '',
      },
      MR_No: '',
    }
    // console.log(cookies.get('token'));
    this.MR_No = this.MR_No.bind(this);

  }
  handleClick() {

    var Register = {
      patientname: this.state.Register.Name,
      patientfathername: this.state.Register.Name2,
      age: this.state.Register.Age,
      gender: this.state.Register.Gender,
      telephone1: this.state.Register.Telephone1,
      telephone2: this.state.Register.Telephone2,
      mrnumber: this.state.MR_No
    };
    var formBody = [];
    console.log("Register values", Register);
    for (var property in Register) {
      var encodedKey = encodeURIComponent(property);
      var encodedValue = encodeURIComponent(Register[property]);
      formBody.push(encodedKey + "=" + encodedValue);
    }

    formBody = formBody.join("&");

    console.log("Form Body", formBody);
    var Authtoken = cookies.get('token')
    var finalAuthtoken = 'Bearer ' + Authtoken

    fetch('http://xxx-xxx-xxx-xxx-xxx.compute-1.amazonaws.com:3000/addpatient', {
      method: 'POST',
      withCredentials: true,

      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
        'Authorization': finalAuthtoken

      },
      body: formBody

    }).then(function (resp) {
      if (resp.ok) {
        toastr.options = {
          positionClass: 'toast-top-right',
          hideDuration: 3000,
          timeOut: 100
        }
        toastr.clear()
        setTimeout(() => toastr.success(`Patient registered`), 300)
      }
    })

    console.log('handle click login')
    console.log('user', this.state.Register)

  }
  handleChange(changeValue, event) {
    this.state.Register[changeValue] = event.target.value;
    this.setState = ({
      Register: this.state.Register,
      // password:this.state.password
    })
    console.log('Register', this.state.Register)
  }




  MR_No() {

    const self = this;
    axios({
      method: 'get',
      url: 'http://xxx-xx-xxx-xxx-xxx.compute-1.amazonaws.com:3000/createmrnumber',

    })
      .then(function (json) {
        var data = json;
        console.log(json.data);
        var mr = json.data
        console.log(mr);

        self.setState({
          MR_No: mr
        })

        console.log("MR Number", self.state.MR_No);

      }).catch(error => {
        console.log(error)
      })


  }

  render() {
    const { classes } = this.props;
    return (
      <div >

        <RecAppbar />
        <h2 style={{ color: '#2699FB' }}>Register Patient</h2>
        <div>
        <TextField
          disabled
          // id="outlined-disabled"
          label={this.state.MR_No}
          defaultValue={this.state.MR_No}
          className={classes.textField}
          margin="normal"
          variant="outlined"
        />
         <Button variant="outlined" style={{ backgroundColor: '#2699FB',marginTop:'2%' }} onClick={(event) => this.MR_No(event)}><b>Generate MR_No</b></Button>
         </div>
        <br></br>
        <TextField
          label="Name"
          value={this.state.Name}
          required
          onChange={this.handleChange.bind(this, 'Name')}
          margin="normal"
          variant="outlined"
          className={classes.textField}
        />



        <TextField
          label="Husband/Father Name"
          required
          value={this.state.Name2}
          onChange={this.handleChange.bind(this, 'Name2')}
          margin="normal"
          variant="outlined"
          className={classes.textField}
        />

        <br></br>
        <TextField
          label="Age"
          required
          value={this.state.Age}
          onChange={this.handleChange.bind(this, 'Age')}
          margin="normal"
          variant="outlined"
          className={classes.textField}
        />

        <TextField
          label="Telephone#1"
          required
          value={this.state.Telephone1}

          onChange={this.handleChange.bind(this, 'Telephone1')}
          margin="normal"
          variant="outlined"
          className={classes.textField}
        />

<br></br>
        <TextField
          label="Telephone#2"
          required
          value={this.state.Telephone2}

          onChange={this.handleChange.bind(this, 'Telephone2')}
          margin="normal"
          variant="outlined"
          className={classes.textField}
        />


          <FormControl variant="outlined" className={classes.TextField}>
            <InputLabel style={{marginTop:'7%'}}
              ref={ref => {
                this.InputLabelRef = ref;
              }}
              htmlFor="outlined-age-simple"
            >
              Role
          </InputLabel>

            <Select style={{ width: 222, marginRight: "100%", marginTop:'7%' }}
              required
              value={this.state.Gender}
              onChange={this.handleChange.bind(this, 'Gender')}

              input={
                <OutlinedInput
                  labelWidth={this.state.labelWidth}
                  // name={this.state.Gender}
                  id="outlined-age-simple"
                  value={this.state.Gender}
                />

              }
            >
              <MenuItem value={'Male'}>Male</MenuItem>
              <MenuItem value={'Female'}>Female</MenuItem>
              <MenuItem value={'Other'}>Other</MenuItem>

            </Select>


          </FormControl>

                <br></br>

        <Button type="submit" variant="outlined" style={{ backgroundColor: '#2699FB', position: 'relative' }} onClick={(event) => this.handleClick(event)}><b>Register   Patient</b></Button>






      </div>


    )
  }
}
RegisterPatient.propTypes = {
  classes: PropTypes.object.isRequired,
};
export default withStyles(styles)(RegisterPatient)

设置其他文本框属性后,我想设置MR_No的属性。

1 个答案:

答案 0 :(得分:0)

问题是self未被设置为正确的范围..也许尝试调用箭头函数来访问组件函数调用?

MR_No() {

    const setMR_No = (val) => this.setState({ MR_No: val })

    axios({
      method: 'get',
      url: 'http://xxx-xx-xxx-xxx-xxx.compute-1.amazonaws.com:3000/createmrnumber',

    })
      .then(function (json) {
        var data = json;
        console.log(json.data);
        var mr = json.data
        console.log(mr);

        setMR_No(mr)

      }).catch(error => {
        console.log(error)
      })
  }