简体   繁体   English

以新形式反应更新状态

[英]React update state in a new form

How can I update the state in a new form?如何以新形式更新状态? I want to convert an image into base64 when uploaded and push it to the firebase.我想在上传时将图像转换为 base64 并将其推送到 firebase。

However, I got an TypeError: this.setState is not a function error.但是,我得到了一个TypeError: this.setState is not a function error。

I also tried to update the value of input, but didn't work.我也尝试更新 input 的值,但没有用。 document.getelementbyid("image").value = reader.result

Thank you!谢谢!

import React from 'react'
import PropTypes from 'prop-types'
import { Formik, Field, Form } from 'formik'
import { TextField } from 'formik-material-ui'
import { makeStyles } from '@material-ui/core/styles'
import Button from '@material-ui/core/Button'
import Dialog from '@material-ui/core/Dialog'
import DialogTitle from '@material-ui/core/DialogTitle'
import DialogActions from '@material-ui/core/DialogActions'
import DialogContent from '@material-ui/core/DialogContent'
import styles from './NewProjectDialog.styles'

const useStyles = makeStyles(styles)

function NewProjectDialog({ onSubmit, open, onRequestClose }) {
  const classes = useStyles()

  function handleSubmit(values, { setSubmitting }) {
    return onSubmit(values).then(() => {
      setSubmitting(false)
    })
  }

  function previewFile() {
    const preview = document.querySelector('img');
    const file = document.querySelector('input[type=file]').files[0];
    const reader = new FileReader();

    reader.addEventListener("load", function () {
      // convert image file to base64 string
      preview.src = reader.result;
      this.setState({image: reader.result})
    }, false);

    if (file) {
      reader.readAsDataURL(file);
    }

    this.previewFile = this.preview.bind(this)
  }

  return (
    <Dialog open={open} onClose={onRequestClose}>
      <DialogTitle id="new-project-dialog-title">New Project</DialogTitle>
      <Formik initialValues={{ name: '' }} onSubmit={handleSubmit}>
        {({ errors, isSubmitting }) => (
          <Form className={classes.root}>
            <DialogContent>
              <Field
                name="isbn"
                label="ISBN"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="title"
                label="Title"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="status"
                label="Status"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                name="price"
                label="Price"
                component={TextField}
                margin="normal"
                fullWidth
              />
              <Field
                id="image"
                name="image"
                component={TextField}
                style={{display:"none"}}
              />
              <input type="file" onChange={previewFile}/>
              <img src="" height="200" alt="Image preview..."></img>
            </DialogContent>
            <DialogActions>
              <Button onClick={onRequestClose} color="secondary">
                Cancel
              </Button>
              <Button type="submit" color="primary" disabled={isSubmitting}>
                {isSubmitting ? 'Creating...' : 'Create'}
              </Button>
            </DialogActions>
          </Form>
        )}
      </Formik>
    </Dialog>
  )
}

NewProjectDialog.propTypes = {
  onSubmit: PropTypes.func.isRequired,
  open: PropTypes.bool.isRequired,
  onRequestClose: PropTypes.func.isRequired
}

export default NewProjectDialog


I modified the code but the image was not stored in the firebase... 我修改了代码,但图像没有存储在 Firebase 中...

 function NewProjectDialog({ onSubmit, open, onRequestClose }) { const classes = useStyles() const [image, setImage] = useState({image: null}); (Omitted) function previewFile() { const preview = document.querySelector('img'); const file = document.querySelector('input[type=file]').files[0]; const reader = new FileReader(); reader.addEventListener("load", function () { // convert image file to base64 string preview.src = reader.result; setImage({image: reader.result}); }, false); if (file) { reader.readAsDataURL(file); } }
 -M0EVfPfzF1vjQ4wLXLU createdAt: 1581881931504 createdBy: "YcGWgfdbk2hs8CcWSdtsicYncyB3" isbn: "asdfa" name: "" price: "asdfasd" status: "asfdasfd" title: "asfdasfd"

Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text Meaningless text无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本无意义的文本

I guess this issue is coming from that this.setState can be used only in class based component.我想这个问题来自this.setState只能在基于类的组件中使用。 In function components like what you have - NewProjectDialog - you can use useState hook where you can create your state and the updater function.在像您拥有的功能组件 - NewProjectDialog - 您可以使用useState钩子,您可以在其中创建状态和更新程序功能。

What does useState return? useState返回什么? It returns a pair of values: the current state and a function that updates it.它返回一对值:当前状态和更新它的函数。

So you could have the defined state as:因此,您可以将定义的状态为:

const [image, setImage] = useState({image: null});

And instead of this.setState({image: reader.result}) you would modify as the following:而不是this.setState({image: reader.result})你可以修改如下:

// updating value
setImage({image: reader.result});

Read further here: Using the State Hook在此处进一步阅读:使用状态挂钩

I hope that helps!我希望这有帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM