我正在使用redux管理组件的状态,并使用新映射从redux存储访问该组件的数组数据。我需要能够使我的图标的值在单击时增加。我不确定如何访问我的反应值以使其正常工作并处理我的click事件。我需要使用updateUploadReaction
函数更新卡的反应。我希望单击图标时反应的值增加1
我写了两行伪代码,以更好地理解实现它的可能方法。如果您需要直接访问代码,请使用link。它在主目录下
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 uploads = new Map();
USER_UPLOADS.forEach(userUpload => {
const { id } = userUpload;
uploads.set(id, userUpload);
});
return uploads;
}
function updateUploadReaction(id, reaction, uploads) {
const updatedUploads = new Map([...uploads.entries()]);
const userUpload = updatedUploads.get(id);
const { type } = updatedUploads.reaction;
// I need to get access values and increment
// Set reaction by type to value
*// value.set(type, reaction);*
updatedUploads.set(id, userUpload);
return updatedUploads;
}
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: updateUploadReaction(action.id, action.reaction, uploads),
};
}
default:
return state;
}
};
constants.js
/** @constant */
export const INITIAL_STATE = {
uploads: new Map(),
};
export const USER_UPLOADS = [
{
id: 0,
// eslint-disable-next-line max-len
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,
// eslint-disable-next-line max-len
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,
// eslint-disable-next-line max-len
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',
},
];
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 { actions: { requestUploadList } } = this.props;
requestUploadList();
}
updateReaction = (id, reaction) => {
const { actions: { updateReaction } } = this.props;
updateReaction(id, reaction);
}
render() {
const { uploads } = this.props;
const values = [...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 = {
actions: PropTypes.object,
uploads: PropTypes.instanceOf(Map),
};
const mapStateToProps = state => ({
uploads: getUploads(state),
});
const mapDispatchToProps = dispatch => ({
actions: bindActionCreators(actions, dispatch),
});
export default connect(mapStateToProps, mapDispatchToProps)(Home);
答案 0 :(得分:0)
使代码工作的两件事-
1)Home.jsx
-您没有在onClick
组件中使用IconText
,而只是通过它。
const IconText = ({ type, text, onClick }) => {
return (
<span>
<Icon type={type} style={ICON} onClick={onClick} />
{text}
</span>
);
};
2)Reducers.js
-我不确定您要在哪里编写增量逻辑,我刚刚在reducer中编写了它,并且可以正常工作。
function updateUploadReaction(id, reaction, uploads) {
const updatedUploads = new Map([...uploads.entries()]);
const userUpload = updatedUploads.get(id);
userUpload.reactions[reaction] = userUpload.reactions[reaction] + 1;
updatedUploads.set(id, userUpload);
return updatedUploads;
}
最后一个有效的代码sanbox link
希望有帮助!