this.props.images
is not properly updating when I dispatch the array of images. The array just displays as empty, though the resulting array is not.
I've linked my repo for the project and listed the files that need to be referenced.
The files that you need to look at are as follows:
If you want to help with this project by contributing that'd be great! :)
maybe you should use the componentWillReceiveProps in the Component life cycle
see react docs --> here
or just use pureComponents (functions nether classes)
pureComponents updates on props by default
I tried running your app, but it didn't work. So the code below is assuming that everything else is set up and working properly in your app.
Instead of using the class decorator @
, try connecting directly to the class (also, I'd highly recommend cleaning up your code, it's really hard to read).
Several notes:
this.update()
-- update WHAT!?!? While it makes sense to you, to a developer who has never seen your app, they'll ask the same question)image
and images
. What's the difference? If one is a number for indexing and the other is an array for images, that's okay, you can still use a single reducer (as shown below).actions
folder to handle Redux actions and a types
folder for Redux typesfetch
)Upload Images
form. Don't lump it with your Images
component.state
.types/index.js (redux action types)
export const UPDATE_IMAGE_INDEX = "UPDATE_IMAGE_INDEX";
export const UPDATE_IMAGES = "UPDATE_IMAGES";
reducers/imagesReducer.js (structure your switch/case
s like so)
const initialState = {
index: 0,
data: []
}
const imagesReducer = (state=initialState, { type, payload }) => { //es6 destructing -- type=action.type, payload=action.payload
switch (type) {
case 'UPDATE_IMAGE_INDEX':
return { ...state, index: payload } // accessible via state.images.index
case 'UDPATE_IMAGES':
return {...state, data: payload } // accessible via state.images.data
default:
return state
}
};
export default imagesReducer;
actions/imageActions (redux action creators)
import * as types from '../types';
// the following is a Redux thunk action (thunk handles returned async functions -- you have to install it and add it as middleware)
export const fetchImages = (id, type) => dispatch => (
fetch(`/images/${type}/${id}`) // fetch images
.then(res => res.json()) // turn result into JSON
.then(({ result }) => dispatch({ type: types.UPDATE_IMAGES, payload: result })) // send result to `imagesReducer`
.catch(() => console.log('Network error...'));
)
// this updates the image index
export const updateImageIndex = payload => dispatch => (
dispatch({ type: types.UPDATE_IMAGE_INDEX, payload })
)
// this should upload an image, save it, then return all current images
export const uploadImage = (type, id, data) => dispatch => (
fetch(`/images/${type}/${id}`, {
method: 'POST',
body: data
}
)
.then(res => res.json())
.then(({ result }) => dispatch({ type: types.UPDATE_IMAGES, payload: result }))
.catch(() => dispatch({ type: 'UPDATE_ERROR', payload: { message: 'Network error...try again later!'} }));
)
components/Content/Profile/ShowImages.js (displays images -- nothing else; also, allows you to view them one by one via buttons)
import React, { PureComponent } from 'react'
import { connect } from 'react-redux'
import { fetchImages, updateImageIndex } from '../../../actions/imageActions';
class ShowImages extends PureComponent {
componentDidMount = () => {
inputs.lazyload(`/css/images.min.css`).catch(() => console.log('Network error...'));
this.props.fetchImages(this.props.type, this.props.id); // fetches images via redux action creator shown above
}
handlePrevClick = e => {
const { index, images } = this.props;
if (index-1 <== images.length) {
this.props.updateImageIndex(index-1); // reduces redux image index by 1 via redux action creator shown above
}
}
handleNextClick = () => {
const { index, images } = this.props;
if (index+1 <== images.length) {
this.props.updateImageIndex(index+1); // increases redux image index by 1 via redux action creator shown above
}
}
// ideally this should be done BEFORE being sent to the front-end, as is, every time this.props.index is updated, this has resort them -- ruins client-side performance and wastes resources.
sortImages = () => {
return this.props.images.sort((a, b) => {
if (a.isDefault && b.isDefault) return a.src.localeCompare(b.src);
return a.isDefault || b.isDefault;
});
}
render = () => {
const { index, images } = this.props;
const sortedImages = this.sortImages();
const prev = images.length && index > 0 ? '<' : '+';
const next = images.length && index < images.length ? '>' : '+';
return (
<div className='images'>
<button className='prev' onClick={this.handlePrevClick}>
{prev}
</button>
<img src={sortedImages[index]} />
<button className='next' onClick={this.handleNextClick}>
{next}
</button>
</div>
);
}
}
const mapStateToProps = state => ({
images: state.images.data,
index: state.images.index,
user: state.user,
type: store.current.type
})
const mapDispatchToProps = dispatch => ({ fetchImages, updateImageIndex });
export default connect(mapStateToProps, mapDispatchToProps)(ShowImages)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.