存储更改后,react redux不会更改组件

时间:2018-03-22 16:59:13

标签: reactjs redux react-redux

我说要学习反应和减少,所以我认为有许多事情我不知道。 我在商店更改时错过了重新渲染组件的问题。

这是我的项目结构: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}}未被调用。

为什么呢?任何人都可以帮助我吗?

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;
}

这样您就可以返回一个新的数组而不是旧数组(带有已排序的元素)。