I am designing a profile page for my site using ReactJS
. Now my question is how do I upload the image from local machine and save it to the database and also displaying it in the profile page
import React, {Component} from 'react'; import { connect } from 'react-redux'; import { AccountAction } from '../../actions/user/AccountPg1Action'; import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup'; class AccountInfo extends Component { constructor(props) { super(props) this.state = { currentStep: 1, userAccountData: { userid: '', useravtar: '', attachement_id: '', } } } handleFileUpload = (event) => { this.setState({useravtar: event.currentTarget.files[0]}) }; handleChange = event => { const {name, value} = event.target this.setState({ [name]: value }) } handleSubmit = event => { let that = this; const { AccountAction } = that.props; event.preventDefault(); let accountInputs = { userid: 49, useravtar: that.state.image, attachement_id: 478, } that.setState({ userAccountData: accountInputs, }) AccountAction(accountInputs) } AccountInfoView = () => { console.log(this.state.useravtar) return ( <section id="account_sec" className="second_form"> <div className="container"> <React.Fragment> <Formik initialValues={‌{ file: null, email: '', phone: '' }} validationSchema={accountInfoSchema} render={(values) => { return( <Form onSubmit={this.handleSubmit}> <Step1 currentStep={this.state.currentStep} handleChange={this.handleChange} file= {this.state.useravtar} handleFileUpload={this.handleFileUpload} /> </Form> ); }} /> </React.Fragment> ) } render() { return ( <div>{this.authView()}</div> ) } } function Step1(props) { console.log(props.useravtar) if (props.currentStep !== 1) { return null } return( <div className="upload"> <label htmlFor="profile"> <div className="imgbox"> <img src="images/trans_116X116.png" alt="" /> <img src={props.useravtar} className="absoImg" alt="" /> </div> </label> <input id="file" name="file" type="file" accept="image/*" onChange={props.handleFileUpload}/> <span className="guide_leb">Add your avatar</span> </div> ) }
When I do console in handleChange
action for event.target.file[0] it responds with undefined.
Also, doing a console.log(this.state.useravtar)
in handleSubmit
action it shows a pathname like c:/fakepath/imgname.jpg
P.S: I have a multiple forms so I am using it in a Step
wise. And i am using Redux Reducer for storing the data.
I have referred this link but my requirement is not looking like this.
Uploading one file 📎 In the Formik docs there are no indications or directions for file uploading but it as simple as handling a react-select select box. All you really need is an entry for the values of Formik (in this case called file) and setup the onChange to use Formiks' setFieldValue function.
FormIk does not support file uploading and we need to do it in custom way. Just trigger onChange event and set the file. Show activity on this post. onSubmit you can access file using values obj like values.
Using Formik's handleChange The handleChange method updates the form values based on the input's name attribute that was changed. The handleChange method is used with input elements. Field component internally updates the values without the need of implementing the handleChange method.
Formik doesnot support fileupload by default, But you can try the following
<input id="file" name="file" type="file" onChange={(event) => { setFieldValue("file", event.currentTarget.files[0]); }} />
Here "file"
represents the key that you are using for holding the file
And on submit you can get the filename, size etc for the file by using
onSubmit={(values) => { console.log({ fileName: values.file.name, type: values.file.type, size: `${values.file.size} bytes` })
If you want to set the file into components state then you can use
onChange={(event) => { this.setState({"file": event.currentTarget.files[0]})}; }}
According to your code, you have to handle file upload as below
In AccountInfo add a function to handle file upload
handleFileUpload = (event) => { this.setState({WAHTEVETKEYYOUNEED: event.currentTarget.files[0]})}; }
And pass the same function to Step1 Component as below
<Step1 currentStep={this.state.currentStep} handleChange={this.handleChange} file= {this.state.image} handleFileUpload={this.handleFileUpload} />
In Step1 Component where you upload the file, Change the input as
<input id="file" name="file" type="file" accept="image/*" onChange={props.handleFileUpload}/>
If you need to preview the uploaded image then you can create a blob and pass the same as source for image as below
<img src={URL.createObjectURL(FILE_OBJECT)} />
EDIT-1
As URL.createObjectURL
method is deprecated due to security issues, we need to use srcObject
for Media Elements, to use that you can use ref
to assign srcObject, for example
Assuming you are using class Components,
Constructor
in constructor you can use
constructor(props) { super(props) this.imageElRef = React.createRef(null) }
HANDLE CHANGE FUNCTION
handleFileUpload = (event) => { let reader = new FileReader(); let file = event.target.files[0]; reader.onloadend = () => { this.setState({ file: reader.result }); }; reader.readAsDataURL(file); }
Element
<img src={this.state.file} />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With