我说要学习反应和减少,所以我认为有许多事情我不知道。 我在商店更改时错过了重新渲染组件的问题。
这是我的项目结构:https://i.stack.imgur.com/tJJSg.png
这是我的代码:
App.js:
class App extends Component {
render() {
return (
<div className="App">
<Nav sortByDate={()=>{this.props.sortBy(SORT_BY_DATE)}} sortByLikes={()=>{this.props.sortBy(SORT_BY_LIKES)}} />
<Items comments={this.props.comments} getList={()=>{this.props.sortBy(GET_LIST)}}/>
</div>
);
}
}
const mapStateToProps = (state) => {
return {
comments: state.comments
};
};
const mapDispatchToProps = (dispatch) => {
return {
sortBy: (action) => {
dispatch(sortBy(action));
}
};
};
export default connect (mapStateToProps, mapDispatchToProps) (App);
CommentList.js:
class ListItems extends Component {
constructor(props){
super(props);
this.state = {
comments: props.comments
};
}
componentWillMount() {
this.props.getList();
}
componentWillReceiveProps(nextProps) {
if (this.props.comments !== nextProps.comments) {
this.setState({
comments: nextProps.comments
});
}
}
getComments() {
return (this.state.comments.map(function (object) {
return <Item numLikes={object.num_like} id={object.id} comment={object.comment} date={object.date}
sender={object.sender}/>
}));
}
render() {
return (
<Container>
<Row>
<Col lg={2} md={1} xs={0}/>
<Col lg={8} md={10} xs={12}>
{this.getComments()}
</Col>
<Col lg={2} md={16} xs={0}/>
</Row>
</Container>
);
}
}
export default ListItems;
Reducers.js:
const listReducer = (state = {comments: []}, action) => {
function toDate(dateStr) {
const [day, month, year] = dateStr.split("/")
return new Date(year, month - 1, day)
}
function commentSortedByDate(comments) {
const sorted = comments.sort(function(a, b) {
return toDate(b.date) - toDate(a.date);
})
return sorted;
}
function commentSortedByLikes(comments) {
const sorted = comments.sort(function(a, b) {
return parseInt(b.num_like) - parseInt(a.num_like);
})
return sorted;
}
switch (action.type) {
case SORT_BY_DATE:
console.log("sort by date");
state={
comments: commentSortedByDate(state.comments)
}
break;
case SORT_BY_LIKES:
console.log("sort by likes");
state={
comments: commentSortedByLikes(state.comments)
}
break;
case GET_LIST:
state = {
comments: action.payload
}
break;
}
return state;
};
export default listReducer;
问题当然在于这两个组成部分。
我有3个动作:
GET_LIST
(在中间件中调用休息服务获取评论的json并更新商店)。SORT_BY_DATE
(在reducer中按日期排序注释数组并更新商店)。SORT_BY_LIKES
(同)
商店中的评论有效排序。首先,应用程序会自动调度GET_LIST
操作并运行,将带有注释的道具正确传递给CommentList.js
组件,并成功呈现CommentItem
列表。
现在问题:
单击Navbar组件中的按钮将调度更新商店的SORT_BY
操作,最后调用App中的MapStateToProps
功能,但这次CommentList
保持不变componentWillReceiveProps
1}}未被调用。
为什么呢?任何人都可以帮助我吗?
答案 0 :(得分:0)
您正在改变状态(sort function)而不是在reducer中创建新数组。这可以防止组件重新呈现,因为它未通知更改。要修复它,你可以使你的函数变得纯净:
function commentSortedByDate(comments) {
const copy = [...comments];
copy.sort(function(a, b) {
return toDate(b.date) - toDate(a.date);
})
return copy;
}
function commentSortedByLikes(comments) {
const copy = [...comments];
copy.sort(function(a, b) {
return parseInt(b.num_like) - parseInt(a.num_like);
})
return copy;
}
这样您就可以返回一个新的数组而不是旧数组(带有已排序的元素)。