Я обрабатываю состояния моего компонента с использованием избыточности и обращаюсь к данным массива для компонента из хранилища избыточности, используя новую карту. Мне нужно, чтобы при нажатии на мой обработчик onClick
значение моего значка увеличивалось. Функция updateItemReactions
должна обрабатывать действие для меня. Кажется, я что-то пропускаю. Ссылка на код под домашними компонентами
constants.js
/** @constant */
export const INITIAL_STATE = {
uploads: new Map(),
};
export const USER_UPLOADS = [
{
_id: 0,
image: 'http://sugarweddings.com/files/styles/width-640/public/1.%20The%20Full%20Ankara%20Ball%20Wedding%20Gown%20@therealrhonkefella.PNG',
reactions: {
dislike: 0,
like: 0,
maybe: 0,
},
story: "It's my birthday next week! What do you think?",
user: 'Chioma',
},
{
_id: 1,
image: 'https://dailymedia.com.ng/wp-content/uploads/2018/10/7915550_img20181007141132_jpeg01c125e1588ffeee95a6f121c35cd378-1.jpg',
reactions: {
dislike: 0,
like: 0,
maybe: 0,
},
story: 'Going for an event. Do you like my outfit?',
user: 'Simpcy',
},
{
_id: 2,
image: 'https://i0.wp.com/www.od9jastyles.com/wp-content/uploads/2018/01/ankara-styles-ankara-styles-gown-ankara-tops-ankara-gowns-ankara-styles-pictures-latest-ankara-style-2018-latest-ankara-styles-ankara-ankara-styles.png?fit=437%2C544&ssl=1',
reactions: {
dislike: 0,
like: 0,
maybe: 0,
},
story: 'Saturdays are for weddings. Yay or nay?',
user: 'Angela',
},
];
actions.js
import { UPDATE_REACTION, REQUEST_UPLOAD_LIST } from './actionTypes';
/**
* Triggers request to react on a post
*
* @function
* @return {Object} The {@link actionTypes.REQUEST_UPLOAD_LIST REQUEST_UPLOAD_LIST}
* action.
*/
export function updateReaction(_id, reaction) {
return {
_id,
reaction,
type: UPDATE_REACTION,
};
}
/**
* Triggers request for the lists of uploads
*
* @function
* @return {Object} The {@link actionTypes.REQUEST_UPLOAD_LIST REQUEST_UPLOAD_LIST}
* action.
*/
export const requestUploadList = payload => ({
payload,
type: REQUEST_UPLOAD_LIST,
});
reducers.js
import { UPDATE_REACTION, REQUEST_UPLOAD_LIST } from './actionTypes';
import { INITIAL_STATE, USER_UPLOADS } from './constants';
/**
* Creates a Javascript Map with the user uploads mapped by id
*
* @param {Array} USER_UPLOADS - a users uploads
* @return {Map} - the user uploads
*/
function generateUploadsMap() {
const setOfUserUploads = new Map();
USER_UPLOADS.forEach(userUpload => {
const { _id } = userUpload;
setOfUserUploads.set(_id, userUpload);
});
return setOfUserUploads;
}
function updateItemReactions(_id, reaction) {
const newValue = new Map();
const upload = USER_UPLOADS.get(_id);
upload.reactions = {
...upload.reactions,
[reaction]: upload.reactions[reaction] + 1,
};
newValue.set(_id, upload);
return newValue;
}
export default (state = { ...INITIAL_STATE }, action) => {
switch (action.type) {
case REQUEST_UPLOAD_LIST: {
return {
...state,
uploads: generateUploadsMap(),
};
}
case UPDATE_REACTION: {
const { uploads } = state;
return {
...state,
uploads: updateItemReactions(action._id, action.reaction, uploads),
};
}
default:
return state;
}
};
home.js
import PropTypes from 'prop-types';
import React from 'react';
import { Avatar, Card, Icon, List } from 'antd';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { LIST_TEXTS, STYLES } from '../constants';
import * as actions from '../actions';
import { getUploads } from '../selectors';
const { AVATAR, CARD_CONTAINER, CARD_LIST, ICON, USER_LIST } = STYLES;
const { INNER, MORE, UPLOAD, VERTICAL } = LIST_TEXTS;
const IconText = ({ type, text }) => (
<span>
<Icon type={type} style={ICON} />
{text}
</span>
);
function createReactionsIcon(item, updateReaction) {
const { like, dislike, maybe } = item.reactions;
const icons = [
{ reaction: 'like', text: `${like}`, type: 'heart' },
{ reaction: 'dislike', text: `${dislike}`, type: 'dislike' },
{ reaction: 'maybe', text: `${maybe}`, type: 'meh' },
];
return icons.map(({ reaction, text, type }) => (
<IconText
onClick={() => updateReaction(item._id, reaction)}
key={reaction}
type={type}
text={text}
/>
));
}
class Home extends React.Component {
componentDidMount() {
const { requestUploadList } = this.props.actions;
requestUploadList();
}
updateReaction = (_id, reaction) => {
const { updateReaction } = this.props.actions;
updateReaction(_id, reaction);
}
render() {
const { uploads } = this.props;
const values = Array.from(uploads.values());
return (
<div style={CARD_CONTAINER}>
<List
itemLayout={VERTICAL}
dataSource={values}
renderItem={item => (
<List.Item style={USER_LIST}>
<Card
actions={createReactionsIcon(item, this.updateReaction)}
cover={<img alt={UPLOAD} src={item.image} />}
extra={<Icon type={MORE} />}
hoverable
title={(
<a href="/">
<Avatar src={item.image} style={AVATAR} />
{item.user}
</a>
)}
type={INNER}
style={CARD_LIST}
>
{item.story}
</Card>
</List.Item>
)}
/>
</div>
);
}
}
Home.propTypes = {
uploads: PropTypes.instanceOf(Map),
actions: PropTypes.object,
};
const mapStateToProps = state => ({
uploads: getUploads(state),
});
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(actions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(Home);