简体   繁体   English

更新状态后未重新渲染组件(调用了mapStateToProps)

[英]Component not re-rendered after updating the state (mapStateToProps called)

I'm having a trouble updating the state. 我在更新状态时遇到问题。 I'm using redux so the state is updated on the reducer level. 我正在使用redux,因此状态在reducer级别上进行了更新。 After updating the state from another component a new state is returned with new data. 从另一个组件更新状态后,将使用新数据返回新状态。 mapStateToProps is called but the component is not re-rendering. mapStateToProps被调用,但是该组件未重新呈现。

This is my component 这是我的组成部分


class Users extends Component {

    render() {
        console.log("RENDERING ------");
        const usernames= this.props.usernames.map((username, key) => {
            return (<div key={key} className="card mt-2">
                <div className="card-body">
                    {username}
                </div>
            </div>)

        })

        return (
            <div data-spy="scroll" data-target="#navbar-example3" data-offset="0">
                {usernames}
            </div>

        )

    }

}


const mapStateToProps = state => {
    console.log("STATE", state);
    return {
        usernames: state.usernames.data
    }
}


export default connect(mapStateToProps, null)(Users);

when loading the component the usernames are displayed. 加载组件时,将显示用户名。 but adding a new username from another component the mapStateToProps is called but the component is not re-rendered. 但会从另一个组件中添加新的用户名,即会调用mapStateToProps,但不会重新呈现该组件。

Parent Component 父组件

class Parent extends Component {

    render() {
        return (
            <div className="container">
                <div className="row">
                    <div className="col">
                        <Editor />
                    </div>
                    <div className="col">
                        <Users />
                    </div>
                </div>

            </div>
        )
    }

This is the editor component where I'm dispatching the action 这是我在其中分派动作的编辑器组件


class Editor extends Component {

    state = {
        user: ""
    }

    handleChange = event => {
        this.setState({ user: event.target.value });
    }

    onSubmit = e => {
        e.preventDefault();
        this.props.addUser(this.state.user);
    }

    render() {
        return (
            <form onSubmit={this.onSubmit}>
                <div className="form-group">
                    <label htmlFor="exampleFormControlTextarea1">User</label>
                    <textarea className="form-control" id="exampleFormControlTextarea1" rows="3" value={this.state.user} onChange={this.handleChange} ></textarea>
                </div>
                <button type="submit" className="btn btn-primary mb-2">Submit</button>

            </form>
        )
    }
}

const mapDispatchToProps = dispatch => {
    return {
        addUser: (user) =>
            dispatch(addUser(user))
    }
}

export default connect(null, mapDispatchToProps)(Editor);


You are mapping the usernames prop in your mapStateToProps , but not making use of it in your component. 您将在mapStateToProps中映射usernames prop,但未在组件中使用它。 You are in fact creating a new variable called usernames and assigning it to the result of a map on this.props.messages . 实际上,您正在创建一个名为usernames的新变量,并将其分配给this.props.messages上的map结果。

Forgive me if I'm not understanding what you're trying to do, but it looks like you should just make use of this.props.usernames , and then when you update it through a dispatch , the prop will update and in turn the component will re-render. 如果我不明白您要做什么,请原谅我,但看起来您应该只使用this.props.usernames ,然后在通过dispatch对其进行更新时,prop将进行更新,然后组件将重新渲染。

After trying and searching online. 经过尝试和在线搜索。 I discovered that the problem was that the component re-render if mapStateToProps returns a different value from the last call. 我发现问题是,如果mapStateToProps返回的值与上次调用的值不同,则重新渲染组件。 For my case I was handling my state on a mutable way. 就我而言,我以一种可变的方式处理自己的状态。 I was using push to add new user to the state on the reducer. 我正在使用推将新用户添加到减速器上的状态。 The solution is to do it in the immutable way using concat: 解决方案是使用concat以不变的方式执行此操作:


const us = [];
us.push(action.results.user);
return { ...state, users: state.users.concat(us) };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM