我将这个组件拆分为便于管理的组件。在拆分之前,一切工作均按预期进行,拆分后,单击名为createReactionsIcon
的图标时出现错误。错误说
TypeError: updateReaction is not a function
onClick
./components/home/components/SingleUpload.jsx:26
23 |
24 | return icons.map(({ key, text, type }) => (
25 | <IconText
> 26 | onClick={() => updateReaction(item.id, key)}
| ^ 27 | key={key}
28 | type={type}
29 | text={text}
如何从我的Home
组件(其中updateReaction
从redux存储返回updateReaction
)正确访问此内容。
SubComponent
import PropTypes from 'prop-types';
import React from 'react';
import { Avatar, Card, Icon, List } from 'antd';
import { LIST_TEXTS, STYLES } from '../constants';
const { AVATAR, CARD_CONTAINER, CARD_LIST, ICON, USER_LIST } = STYLES;
const { INNER, MORE, UPLOAD, VERTICAL } = LIST_TEXTS;
const IconText = ({ type, text, onClick }) => (
<span>
<Icon type={type} style={ICON} onClick={onClick} />
{text}
</span>
);
function createReactionsIcon(item, updateReaction) {
const { like, dislike, maybe } = item.reactions;
const icons = [
{ key: 'like', text: `${like.count}`, type: 'heart' },
{ key: 'dislike', text: `${dislike.count}`, type: 'dislike' },
{ key: 'maybe', text: `${maybe.count}`, type: 'meh' },
];
return icons.map(({ key, text, type }) => (
<IconText
onClick={() => updateReaction(item.id, key)}
key={key}
type={type}
text={text}
/>
));
}
export default class SingleUpload extends React.Component {
render() {
const { values } = this.props;
return (
<div style={CARD_CONTAINER}>
<List
itemLayout={VERTICAL}
dataSource={values}
renderItem={item => {
const { avatar, description, id, uploader: { image, name } } = item;
return (
<List.Item style={USER_LIST}>
<Card
actions={createReactionsIcon(item, this.updateReaction)}
cover={<img alt={UPLOAD} src={image} />}
extra={<Icon type={MORE} />}
hoverable
key={id}
title={(
<a href="/">
<Avatar src={avatar} style={AVATAR} />
{name}
</a>
)}
type={INNER}
style={CARD_LIST}
>
{description}
</Card>
</List.Item>
);
}}
/>
</div>
);
}
}
Home.js
import PropTypes from 'prop-types';
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import SingleUpload from './SingleUpload';
import ComparisonUpload from './ComparisonUpload';
import { STYLES } from '../constants';
import * as actions from '../actions';
import { getUploads } from '../selectors';
const { CARD_CONTAINER } = STYLES;
class Home extends React.Component {
componentDidMount() {
const { actions: { requestUploadList } } = this.props;
requestUploadList();
}
updateReaction = (id, reaction) => {
const { actions: { updateReaction } } = this.props;
const payload = { id, reaction };
updateReaction(payload);
}
render() {
const { uploads } = this.props;
return (
<div style={CARD_CONTAINER}>
<SingleUpload values={[...uploads.values()]} />
<ComparisonUpload values={[...uploads.values()]} />
</div>
);
}
}
Home.propTypes = {
actions: PropTypes.objectOf(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 :(得分:3)
以props
的形式将函数传递给组件,
<SingleUpload values={[...uploads.values()]} updateReaction = {this.updateReaction}/>
现在您可以在子组件中使用它,
<IconText onClick={() => this.props.updateReaction(item.id, key)}
答案 1 :(得分:2)
您可以将updateReaction
从您的父母那里传递给孩子作为回叫
<SingleUpload values={[...uploads.values()]} hanldeReaction={this.updateReaction} />
您可以使用props.hanldeReaction
<Card actions={createReactionsIcon(item, this.props.hanldeReaction)}
答案 2 :(得分:2)
您必须传递在Home中定义为updateReaction()
的道具的SingleUpload
事件处理程序。然后,您可以从组件内部的任何位置访问该道具。
这意味着我们可以清理卡片中的动作道具,因为我们现在只需要传递物品即可。
<Card actions={createReactionsIcon(item)}
和createReactionsIcon
一样,现在我们直接在函数内部调用该道具
function createReactionsIcon(item) {
const { like, dislike, maybe } = item.reactions;
const icons = [
{ key: 'like', text: `${like.count}`, type: 'heart' },
{ key: 'dislike', text: `${dislike.count}`, type: 'dislike' },
{ key: 'maybe', text: `${maybe.count}`, type: 'meh' },
];
return icons.map(({ key, text, type }) => (
<IconText
onClick={() => this.props.updateReaction(item.id, key)}
key={key}
type={type}
text={text}
/>
));
}
总体上减少了冗余代码,听起来像您要实现的目标。