6

hello im trying to make a image upload and preview but i can only find react tutorials on how to do this using class components

import React from 'react';


const AddNew = () => {
    const fileHandler = (event) => {
        console.log(event.target.files[0])
    }
    const alt = (event) => {
        return(event.target.files[0].name)
    }
    const preview = (event) => {
        return (
            URL.createObjectURL(event.target.files[0])
        )
    }
    return (
        <div className="addNew">
            <img src={preview} alt={alt}/>
            <input type="file" onChange={fileHandler} />
        </div>
    )
}

export default AddNew

how do i preview it using this syntax?

i get an error for invalid values for props 'src' and 'alt'

3 Answers 3

9

You need to use state to let React know when to re-render. You can use useState hook to save your component state and file information, and when it changes, React knows it's the time to render.

const AddNew = ({}) => {
    const [file, setFile] = React.useState(null)
    
    const fileHandler = (e) => {
        setFile(e.target.files[0])
    }
    
    return (
        <div>
            <img src={file? URL.createObjectURL(file) : null} alt={file? file.name : null}/>
            <input type="file" onChange={fileHandler} />
        </div>
    )
}



ReactDOM.render(<AddNew />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="root"/>

Sign up to request clarification or add additional context in comments.

Comments

2

Use a bit of state to provide an initial value for src and alt and hold the updated values.

const initialState = { alt: "", src: "" };

const AddNew = () => {
  const [{ alt, src }, setPreview] = useState(initialState);

  const fileHandler = event => {
    const { files } = event.target;
    setPreview(
      files.length
        ? {
            src: URL.createObjectURL(files[0]),
            alt: files[0].name
          }
        : initialState
    );
  };

  return (
    <div className="addNew">
      <img className="preview" src={src} alt={alt} />
      <input accept="image/*" type="file" onChange={fileHandler} />
    </div>
  );
};

Edit image preview

Comments

0

You need to use FileReader to convert the image to base64 string. Assuming you are doing a single file upload, just maintain a state for eg: file and set the state after the filereader onload listener is done reading image.

Working copy of your code is here:


import React, { useState } from "react";

const AddNew = () => {
  const [file, setFile] = useState(null);
  const fileHandler = event => {
    console.log(event.target.files[0]);
    let reader = new FileReader();
    reader.onload = function(e) {
      setFile(e.target.result);
    };
    reader.readAsDataURL(event.target.files[0]);
  };

  return (
    <div className="addNew">
      <img src={file} alt={""} />
      <input type="file" onChange={fileHandler} />
    </div>
  );
};

export default AddNew;

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.