首页 > 解决方案 > 以新形式反应更新状态

问题描述

如何以新形式更新状态?我想在上传时将图像转换为base64并将其推送到firebase。

但是,我得到了一个TypeError: this.setState is not a function错误。

我也尝试更新输入的值,但没有奏效。 document.getelementbyid("image").value = reader.result

谢谢!

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


我修改了代码,但图像没有存储在 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"

无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本 无意义的文本

标签: javascriptreactjs

解决方案


我猜这个问题来自this.setState只能在基于类的组件中使用。在你所拥有的功能组件中NewProjectDialog——你可以使用useState钩子来创建你的状态和更新函数。

返回什么useState?它返回一对值:当前状态和更新它的函数。

因此,您可以将状态定义为:

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

而不是this.setState({image: reader.result})你会修改如下:

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

在此处进一步阅读:使用状态挂钩

我希望这会有所帮助!


推荐阅读