一、应实现的效果
所有评论是一个数组,通过获取所有评论的接口获取。遍历得到的评论,其中点赞按钮:第一次点击向后台发送该评论的key和true,为点赞,第二次点击向后台发送该评论的key和false,为取消点赞。举报按钮,每个评论只能举报一次,举报成功后,该评论的举报按钮为禁用状态。点赞后的数据可以在界面中实时刷新。
二、遇到的问题
由于后台不能跟用户表进行关联,因此不能给我一个该帖子是否被某用户点赞过的字段。这样的话,如果我用state存一个Boolean(isLike: true)类型的值,每次发送点赞接口,将该state传给后台,请求成功后执行
this.setState({isLike: !this.state.isLike})
如果只有一个评论,那么可以实现想要的效果,但是如果有多个评论,点赞第一个评论后,该state的值为false,那么这时点赞第二个评论,向后台发送的就是false,执行了取消点赞,这样做显然是不可行的。
三、解决方法
1、后台把评论表和用户表进行关联,在所有评论的接口中添加两个字段:是否被该用户赞过、是否被该用户举报过。
这样每次执行点赞事件时,根据是否被点赞的字段来决定向后台发送true还是false,举报按钮直接添加style={{disable: item.isReports}},点赞成功时,更改该属性为true即可。
这样做的话,我有一个疑问,如果跟用户表进行关联,那么如果该用户没有登陆,能否对评论进行点赞和举报,即后台能否根据用户的ip来判断是谁点击了点赞和举报。
2、后台不和用户表进行关联,在所有接口中添加两个字段:是否被该用户赞过、是否被该用户举报过,这两个字段都是false,且这两个字段不在后台进行更改,由前端自己更改。即只在界面开始的时候调用请求所有评论的接口。
/**
* @Description:
* @param {key} 该评论的id
* @param {isLike} 是否被点赞过
* @param {isReports} 是否被举报过
*/
//点赞按钮
<button
onClick={() => this.PraiseoClick(item.key, item.isLike)}
style={{ border: 'none', outline: 'none', cursor: 'pointer' }}
>
<Icon type="like" theme={item.isLike ? 'filled' : 'outlined'} />
<span style={{ paddingLeft: 8, cursor: 'auto' }}>{item.likeCount}</span>
</button>
//举报按钮
<button
style={{ border: 'none', outline: 'none', cursor: 'pointer' }}
onClick={() => this.showConfirm(item.key)}
disabled={item.isReports}
>
举报
</button>
//点赞点击函数
PraiseoClick = (e, e1) => {
const obj = {};
obj.id = e;
if (e1 == true) {
obj.isLike = false;
} else {
obj.isLike = true;
}
this.props.CommentReportClick(obj);
<!--由于点赞后页面并没有值进行更改,不会重新渲染,添加一个空的setState,使得使用的ReturnPostEntityData(所有评论数据)能够更新为model里更改的-->
this.setState({});
};
//举报函数
showConfirm = e => {
confirm({
content: '确认该用户有违规行为,是否举报该用户?',
okText: '确认',
okType: 'danger',
cancelText: '取消',
onOk: () => {
let obj = {};
obj.id = e;
obj.isReports = true;
this.props.CommentReportClick(obj);
this.setState({
});
},
});
};
要想实现点赞后的数据,需要在model里改变所有评论数组的数据,代码如下:
/**
* @Description:
* @param {ReturnPostEntityData} 所有评论的数据
* @param {payload} payload.id为点击评论的key
* @param {likeCount} 点赞的数量
* @param {isLike} 点赞的状态
* @param {isReports} 举报的状态
*/
// 点赞或举报评论的model
*likeOrReportsReturnPostEntity({ payload }, { call, put, select }) {
const total = yield select((state) => state.forum.ReturnPostEntityData)
for (let i = 0; i < total.length; i++) {
if (total[i].key == payload.id) {
if (payload.isLike !== undefined) {
if (total[i].isLike) {
total[i].likeCount = total[i].likeCount - 1
total[i].isLike = !total[i].isLike
} else {
total[i].likeCount = total[i].likeCount + 1
total[i].isLike = !total[i].isLike
}
} else {
total[i].isReports = true
}
}
}
const response = yield call(service.likeOrReportsReturnPostEntity_service, payload);
if (response.response.res) {
yield put({
<!--这个type为是改变所有评论数据的reducer-->
type: 'findReturnPostEntityData_reducer',
payload: total,
});
} else {
message.error(response.response.exception, 3)
}
}
//改变所有评论数据的reducer
findReturnPostEntityData_reducer(state, { payload }) {
return { ...state, ReturnPostEntityData: payload }
},
这样就能在页面中实现我们想要的效果啦!效果图如下:
如有错误或有更好的方法,欢迎指点!