Reputation: 1090
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.
However, I got an TypeError: this.setState is not a function
error.
I also tried to update the value of input, but didn't work.
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
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
Upvotes: 0
Views: 53
Reputation: 15166
I guess this issue is coming from that this.setState
can be used only in class based component. In function components like what you have - NewProjectDialog
- you can use useState
hook where you can create your state and the updater function.
What does
useState
return? 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:
// updating value
setImage({image: reader.result});
Read further here: Using the State Hook
I hope that helps!
Upvotes: 1