Passing Redux action to nested child components

时间:2016-10-20 19:58:27

标签: javascript reactjs redux react-redux

I have the following structure

UserPage -> Container
|-----UserList -> Dumb Component
|--- User ->Dumb Component

My action and dispatch obviously is connected to container which is UserPage

function mapStateToProps(state) {
    return {
        users: state.users
    };
}


function matchDispatchToProps(dispatch) {
    return bindActionCreators({deleteUser: deleteUser}, dispatch);
}

export default connect(mapStateToProps, matchDispatchToProps)(UserPage);

Now I am passing deleteUser action to the UserList Component as and then from UserList to the User as

class UserList extends React.Component {
    userList() {
        return this.props.users.map(function(user, i){
            return(
                <User key={i} user={user} deleteUser={this.props.deleteUser} />
                );
        });
    }
}

and finally my leaf component User has this code

class User extends React.Component {

            render() {
                console.info(this.props.deleteUser);
                var user = this.props.user
                return(
                    <tr>
                    <td>{user.id}</td>
                    <td>{user.name}</td>
                    <td>{user.email}</td>
                    <td>{user.createdAt}</td>
                    <td>{user.updatedAt}</td>
                    <td>
                    <a href="#" onClick={()=>this.props.deleteUser(user)}> Delete</a>
                    </td>
                    </tr>
                    );
            }
        }

        export default User;

Now when I pass delete user from UserList to User I get this error

app.bundle.js:29210 Uncaught TypeError: Cannot read property 'props' of undefined

BTW I tried treating deleteUser as function by passing it as ()=>delete user, but I still get that error

2 个答案:

答案 0 :(得分:2)

Your UserList#userList method doesn't have the this you expect. Use an arrow function to preserve the this at the place the function is defined:

userList() {
  return this.props.users.map((user, i) => (
    <User key={i} user={user} deleteUser={this.props.deleteUser} />
  )
}

See this on MDN

答案 1 :(得分:1)

userList() {
    return this.props.users.map(function(user, i){
        return(
            <User key={i} user={user} deleteUser={this.props.deleteUser} />
        );
    });
}

should be

userList() {
    return this.props.users.map((user, i) => {
        return(
            <User key={i} user={user} deleteUser={this.props.deleteUser} />
        );
    });
}

because function(user, i){} has its own this. but using (user, i) => {} previous this is preserved. Learn more on arrow functions here https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions