reactjs - 减速器不能改变返回结果
问题描述
我有 3 个标签,如下所示:ALL|Top100|Spam
在第一次加载页面时,调用 ALL 并收到 257 条返回记录,然后单击“垃圾邮件”选项卡并收到 11 条返回记录。一切正常。
但是当我的当前页面是“垃圾邮件”时,我点击选项卡“全部”,我也收到了 11 条返回记录。错了!结果必须是 257 条记录。
经过调试,我发现这种情况下的“componentWillReceiveProps”只调用了一次,而在第一次加载页面时它调用了2次。导致Reducer 上的状态没有更新。
请帮我。
谢谢你们
这是我的代码:
- 邮递页
/**
* Created by admin on 7/7/17.
*/
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import * as combineActions from '../../actions/index';
import { bindActionCreators } from 'redux';
import PostFilter from './PostFilter';
import PaginationView from '../common/PaginationView';
import { MODAL_TYPES } from '../../const';
import List from '../common/List';
import { I18n } from 'react-redux-i18n';
import toastr from 'toastr';
import moment from 'moment';
// import { showModal } from '../../actions/modalAction';
import PostForm from './PostForm';
const Translate = require('react-redux-i18n').Translate;
class PostPage extends Component {
constructor(props, context) {
super(props, context);
this.state = {
currentPage: props.paging.currentPage,
displayMode: props.displayMode,
searchKey: '',
fromDate: '',
toDate: '',
flgRng: '',
category: '',
};
}
handleChangeDate = (dateName, dateValue) => {
let fromDate, toDate;
if (dateName === 'fromDate') {
fromDate = dateValue;
this.setState({
fromDate,
})
}else{
toDate = dateValue;
this.setState({
toDate,
})
}
}
handlelChangeFilter = (event) => {
this.setState({
[event.target.name]: event.target.value
});
}
handleSearch = () => {
const { searchKey, category } = this.state;
let { flgRng, fromDate, toDate } = this.state;
const params = {};
if(this.validate(fromDate, toDate) ===false)
{
return;
}
if (category) {
params['category.id'] = category;
}
let fD, tD;
if(fromDate){
fD = this.formatDate(fromDate);
flgRng = "1";
}else{
flgRng = "";
}
if(toDate){
tD = this.formatDate(toDate);
}
this.setState({
flgRng
})
this.props.actions.fetchPosts({ SearchKey: searchKey, FromDate: fD, ToDate: tD, FlgRng: flgRng, Query: JSON.stringify(params), Mode: this.props.displayMode})
}
handleShowFormNew = () => {
this.props.actions.showModal(
MODAL_TYPES.POST_NEW,
Object.assign(
{
title: I18n.t('common.delete_confirm'),
message: <PostForm />,
type: 'delete_confirm',
handleOK: () => {},
},
this.props,
),
);
}
validate = (fromDate, toDate) => {
if(!fromDate && toDate){
toastr.error(I18n.t('post.msg_fdate'));
return false;
}
if(fromDate && (fromDate === null || fromDate === "" || Date.parse(fromDate) === NaN)){
toastr.error(I18n.t('post.msg_format_fdate'));
return false;
}
if(toDate && (toDate === null || toDate === "" || Date.parse(toDate) === NaN)){
toastr.error(I18n.t('post.msg_format_tdate'));
return false;
}
if(fromDate && toDate){
fromDate = new Date(fromDate)
toDate = new Date(toDate)
if(fromDate > toDate){
toastr.error(I18n.t('post.msg_compare_fdtd'));
return false;
}
}
}
formatDate = (date) => {
var d = new Date(date),
month = '' + (d.getMonth() + 1),
day = '' + d.getDate(),
year = d.getFullYear();
if (month.length < 2) month = '0' + month;
if (day.length < 2) day = '0' + day;
return [month, day, year].join('-');
}
componentWillMount() {
this.props.actions.setCurrentPage(1);
this.props.actions.fetchPosts();
this.props.actions.fetchCategories();
}
deletePost = (item) => {
this.props.actions.showModal(MODAL_TYPES.CONFIRM_MODAL, Object.assign({
title: I18n.t('common.delete_confirm'),
message: (<Translate value="members.delete_confirm_msg" name={item.content} dangerousHTML />),
type: 'delete_confirm',
handleOK: () => {
this.props.actions.deletePost(item._id)
.then(rs => {
this.props.actions.hideModal();
this.props.actions.triggerRefresh();
toastr.success(I18n.t('post.post_deleted_success'));
}).catch(error => {
this.props.actions.hideModal();
toastr.error(error.message || error);
});
}
}, this.props));
}
componentWillReceiveProps(nextProps) {
const triggerRefresh = this.props.triggerRefresh;
let params = {};
if((this.state.displayMode !== nextProps.displayMode)||(this.state.currentPage !== nextProps.paging.currentPage || triggerRefresh !== nextProps.triggerRefresh)){
this.setState({ currentPage: nextProps.paging.currentPage, displayMode: nextProps.displayMode, searchKey: this.state.searchKey, fromDate: this.state.fromDate, toDate: this.state.toDate, flgRng: this.state.flgRng, category: this.state.category});
if(this.state.category){
params['category.id'] = this.state.category;
}
let fromDate, toDate, flgRng;
if(this.validate(this.state.fromDate, this.state.toDate) ===false)
{
return;
}
if(this.state.fromDate){
fromDate = this.state.fromDate.format("MM-DD-YYYY");
flgRng = "1"
}
if(this.state.toDate){
toDate = this.state.toDate.format("MM-DD-YYYY");
}
this.props.actions.fetchPosts({PageNumber: nextProps.paging.currentPage , SearchKey: this.state.searchKey, FromDate: fromDate, ToDate: toDate, FlgRng: flgRng, Query: JSON.stringify(params), Mode: nextProps.displayMode})
}
}
render() {
const {posts, actions, triggerRefresh, categories, displayMode} = this.props;
const {currentPage} = this.state;
let data = []
let listOptions = {}
if(posts.items.length > 0 && posts.items[0].spamRecs && displayMode ==='spam'){
data = posts.items.length > 0 ? posts.items.map(key => {
key.name = key.author? `${key.author.firstName} ${key.author.lastName}`: '';
key.categoryName = key.category ? key.category.name : '';
key.createdDate = moment(key._created).format('MM/DD/YYYY');
key.reportedDate = key.spamRecs ? moment(key.spamRecs['_created']).format('MM/DD/YYYY') : "";
key.numberReport = key.spamRecs ? key.spamRecs.length : 0
return key;
}): []
listOptions = {
headers: [I18n.t('common.title'), I18n.t('post.category'), I18n.t('post.author'), I18n.t('post.created_date_time'), I18n.t('post.number_report'), I18n.t('post.reported_date'), I18n.t('common.action')],
data: {
items: data,
mapping: ['content', 'categoryName','name', 'createdDate', 'numberReport', 'reportedDate', 'action'],
align:["","","","","center","",""],
render: [
{
key: "content",
render: (item) => {
return <div className="overflow" style={{ width: '180px'}}>{item.content}</div>
}
},
{
key: "categoryName",
render: (item) => {
return <div className="overflow" style={{ width: '140px'}}>{item.categoryName}</div>
}
},
{
key: "name",
render: (item) => {
return <div className="overflow" style={{ width: '60px'}}>{item.name}</div>
}
}
],
},
params: {url: '/posts/detail/%s/info' + '/' +this.state.displayMode, deleteAction: this.deletePost},
count: posts.count
};
}else{
data = posts.items.length > 0 ? posts.items.map(key => {
key.name = key.author? `${key.author.firstName} ${key.author.lastName}`: '';
key.numberComment = key.comments ? key.comments.length: 0;
key.numberLike = key.likes ? key.likes.length : 0;
key.categoryName = key.category ? key.category.name : '';
key.createdDate = moment(key._created).format('MM/DD/YYYY');
return key;
}): []
listOptions = {
headers: [I18n.t('common.title'), I18n.t('post.category'), I18n.t('post.author'), I18n.t('post.created_date_time'), I18n.t('post.number_comment'), I18n.t('post.number_view'), I18n.t('post.number_like'), I18n.t('common.action')],
data: {
items: data,
mapping: ['content', 'categoryName','name', 'createdDate', 'numberComment', 'views', 'numberLike', 'action'],
align:["","","","","center","center","center",""],
render: [
{
key: "content",
render: (item) => {
return <div className="overflow" style={{ width: '180px'}}>{item.content}</div>
}
},
{
key: "categoryName",
render: (item) => {
return <div className="overflow" style={{ width: '140px'}}>{item.categoryName}</div>
}
},
{
key: "name",
render: (item) => {
return <div className="overflow" style={{ width: '60px'}}>{item.name}</div>
}
}
],
},
params: {url: '/posts/detail/%s/info' + '/' +this.state.displayMode, deleteAction: this.deletePost},
count: posts.count
};
}
return (
<div className="table-page">
<h4 className="module-title">{I18n.t('post.page.title')}</h4>
<PostFilter
categories={categories}
searchKey={this.state.searchKey}
fromDate={this.state.fromDate}
toDate={this.state.toDate}
onSearch={this.handleSearch}
onShow={this.handleShowFormNew}
onChangeDate = {this.handleChangeDate}
onChangeFilter = {this.handlelChangeFilter}
/>
<List {...listOptions} />
<PaginationView count={posts.count} currentPage={currentPage} onSelectPage={(page) => {actions.setCurrentPage(page)}}/>
</div>
);
}
}
function mapStateToProps(state, ownProps) {
return {
posts: state.posts.page,
categories: state.posts.categories,
paging: state.paging,
i18n: state.i18n,
triggerRefresh: state.posts.triggerRefresh
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(combineActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(PostPage);
- 帖子减速器
/**
* Created by admin on 7/12/17.
*/
import {POSTS} from '../const/actionTypes';
const initialState = {
page: {
items: [],
count: 0
},
detail: {},
post: {
items: [],
count: 0
},
comment: {
items: [],
count: 0
},
triggerRefresh: false,
categories: [],
currentP: {},
pListComment: [],
pList: [],
pListReporter: [],
};
export default function posts(state = initialState, action) {
switch(action.type) {
case POSTS.FETCH_SUCCESS:
return {...state, page: {items: action.payload.items, count: action.payload.count}};
case POSTS.FETCH_CATEGORY_SUCCESS:
return {...state, categories: action.payload};
case POSTS.TRIGGER_REFRESH:
return {...state, triggerRefresh: !state.triggerRefresh}
case POSTS.GET_POST_DETAIL_SUCCESS:
return { ...state, currentP: Object.assign({}, action.payload) };
case POSTS.CREATE_SUCCESS:
return { ...state, pList: [action.payload, ...state.pList], currentP: {} };
case POSTS.UPDATE_SUCCESS:
let updated = action.payload;
let newItems = state.pList.map(p => {
return p._id === updated._id ? Object.assign({}, p, updated) : p;
});
return { ...state, pList: newItems, currentPS: action.payload };
case POSTS.DELETE_POSTS_SUCCESS:
return { ...state, pList: state.pList.filter(item => item._id != action.payload) };
case POSTS.GET_POST_COMMENT_SUCCESS:
return { ...state, pListComment: action.payload };
case POSTS.GET_POST_REPORTER_SUCCESS:
return { ...state, pListReporter: action.payload };
default:
return state;
}
}
解决方案
推荐阅读
- html - Dreamweaver 说我的样式表不在本地磁盘上?
- json - 如何在解组 JSON 时检查提供的 api 字段的类型
- git - 切换到分支后无法关闭 VisualStudio for Mac 上的 Git 存储库配置窗口
- angular - 我们可以创建一个可以在 react 和 angular 应用程序中访问的全局 redux 存储吗?
- docker - 检索 https://nvd.nist.gov/feeds/json/cve/1.0/nvdcve-1.0-2020.meta 时出错;收到响应码 404
- jquery - 如何使事件可用于动态添加的 html jquery?
- python - 当达到特定的验证准确度时如何停止训练?
- excel - 如何防止 VBA 删除单元格范围运行时错误
- javascript - 如何将变量传递给匹配函数javascript?
- javascript - 如何将弹出窗口中的数据中继到 vue.js 应用程序