Reputation: 383
I’m building this ReactJS application which where I want to upload an image using a click of a button and take it to the next view which is the cropping window and then after cropping it, then I can upload it to the server.
The issue which I’m having right now is how to take an image from 1 view to another view without uploading it to the server?
I tried taking the image path, but unfortunately when the UI refreshes, the path will get flushed.
So, what are the options which I can use in this situation.
Thank you!
Upvotes: 1
Views: 5545
Reputation: 5748
You need to read the image file as a blob and keep it on a parent component which would be in charge of rendering the different components for image manipulation. In some file input element you need a function like this to handle the image selected by the user
handleImageChange = e => {
e.preventDefault();
const reader = new FileReader();
const file = e.target.files[0];
reader.onloadend = () => {
this.setState({
file,
imagePreview: reader.result
});
};
if (file) {
reader.readAsDataURL(file);
}
};
Then you can put that file on as many components as you like. If you want it to persist between refreshes you need to put the file on localStorage or indexedDB
Upvotes: 0
Reputation: 376
The IndexedDB API
is great for client side, large file storage.
Checkout LocalForage. It makes using IndexedDB easy, similar to using localStorage
.
This solution would allow you to store an image client side with all major browsers. You would be able to perform operations on it from a global store and when you wanted to, you would be able to send it to the server.
It also provides your application with an offline cache, where the image would not be lost between sessions or network connections.
Upvotes: 0
Reputation: 1273
So you want to keep your image infos between view. By "view", do you mean a different HTML page? I guess a more standard way of doing things would be to:
If you have never used client-side routing, it looks like that (with react-router):
import { Router, Route, browserHistory } from 'react-router'
// Iy you use redux to handle the state
import { createStore } from 'redux'
import myReducer from 'my-reducer'
const store = createStore(myReducer)
const history = syncHistoryWithStore(browserHistory, store)
// Your view components
function Top(props) { ... }
function UploadImage(props) { ... }
function EditImage(props) { ... }
// The Router itself
ReactDOM.render(
<Router history={history}>
<Route path="/" component={Top} >
<Route path="upload-image" component={UploadImage} />
<Route path="edit-image" component={EditImage} />
</Route>
</Router>)
If you have never used redux before, you can use it this way:
First, create the reducer
import { combineReducers } from 'redux'
const myReducer = combineReducers({ imagePath })
// This is called a reducer function
function imagePath(oldState = "", action) {
switch(action.type) {
case 'SET_PATH':
return action.payload
}
}
Next, connect your component to get the state value (e.g. UploadImage)
const ReduxUploadImage = connect(function(state) {
return {
imagePath: state.imagePath
}
})(UploadImage)
Now if you use ReduxUploadImage
instead of UploadImage
, you can access imagePath
through props.imagePath
. The connect
function also add a dispatch
function to your props.
Finally, you can set the path by calling within your component (but not the render function itself: this would be an anti-pattern)
props.dispatch( { type: 'SET_PATH', payload: "the_path" } )
Finally, it is easy to persist the redux state between pages or refresh using dedicated middleware.
Upvotes: 1
Reputation: 464
Yesterday I worked on similar case. I'm using react-dropzone which returns uploaded files, one of the field in file object is 'preview', it contains uri of currently uploaded file (It's probably cached somehow, but I didn't investigate it yet). In another view you just doing
Upvotes: 2