我有一个用户表,每行都包含一个重置密码链接。
当我单击表格中的第一个按钮(每行都有该按钮)时,它会命中我的处理程序(它存在于我的容器中...我的容器将处理程序作为道具传递下去)它正在击中我的处理程序{{1 }}
但是在try / catch之后调用handleResetPassword
中的setState()
时,它会更新状态,这意味着我的低级组件会收到该状态的通知。因为我正在更新它说因为某些原因出现了错误,尽管所有行都看到了更新状态,因此每行上的每个按钮最终显示出来。我只想要点击的按钮来显示它,而不是全部:
UserContainer.js
handleResetPassword
UserList.js
import { connect } from 'react-redux'
import React, { Component } from 'react'
import * as UserAsyncActions from '../actions/Users/UserAsyncActions'
import Users from '../components/Users/UserList'
class UsersContainer extends Component {
constructor(props){
super(props)
this.state = {
resetPasswordError: null
}
this.handleResetPassword = this.handleResetPassword.bind(this)
}
async componentDidMount() {
await this.props.allUsers(this.props.token)
}
async handleResetPassword(uuid) {
// console.log(e.current.target)
console.log("handleResetPassword invoked!")
try {
await this.props.resetUserPassword()
if(this.props.hasResetPassword){
// show successful message (set message here)
return
}
}
catch(err) {
this.setState({
resetEmailValidationState: 'error',
resetPasswordError: !this.state.hasResetPassword && 'reset failed'
})
}
this.setState({
resetEmailValidationState: 'error',
resetPasswordError: !this.state.hasResetPassword &&
'reset failed'
})
}
render(){
return (
<Users
handleResetPassword={this.handleResetPassword}
resetPasswordError={this.state.resetPasswordError}
users={this.props.users}
/>)
}
}
export const mapStateToProps = state => ({
isRequestingAllUsers: state.user.isRequestingAllUsers,
hasResetPassword: state.user.hasResetPassword,
users: state.user.users,
token: state.auth.token
})
export const mapDispatchToProps = {
allUsers: UserAsyncActions.allUsers,
resetUserPassword: UserAsyncActions.resetPasssord
}
export { Users }
export default connect(mapStateToProps, mapDispatchToProps)(UsersContainer)
注意点击第一个按钮后,如何触及handleResetPassword,并在其中设置状态:
this.setState({ resetEmailValidationState:'error', resetPasswordError:!this.state.hasResetPassword&amp;&amp; '重置失败' })
好吧,现在每个按钮最终显示错误消息,而不是仅显示我点击的第一个按钮:
答案 0 :(得分:0)
您控制按钮道具的状态会传递给您的<Users />
组件,然后该组件会将同一道具传递给<UserList />
,然后再将同一道具传递给每个<User />
。单击按钮时,它会更改<UsersContainer />
中的状态,导致resetPasswordError prop在所有按钮中更改。
您需要在容器的状态中为每个按钮指定一个索引,以便单独切换或为每个<User />
设置一个容器。
编辑:
好的,我会为你的<UserList />
创建一个带连接的容器组件。映射您的handleResetPassword
方法以分派resetPassword操作。 (你应该提取这个动作,你必须编写reducer。)这里的想法是保持对UserList中所有用户的引用,并且每个用户都有一个resetPasswordError属性,除非出现错误,否则该属性为null。如果出现错误,请使用handleResetPassword
方法向用户的uuid分派操作。在reducer中,您可以更新用户的状态。以下是一些代码示例。
const mapStateToProps = ( state ) => {
return {
users: state.users
};
};
const mapDispatchToProps = ( dispatch ) => {
return {
handleResetPassword: ( uuid ) => {
dispatch({
type: "RESET_USER_PASSWORD",
uuid
})
}
};
};
let UserList = ({ users, handleResetPassword }) => {
const userList = users && users.map(
( user ) => (
<User
key={ user.uuid }
user={ user }
handleResetPassword={ handleResetPassword }
resetPasswordError={ user.resetPasswordError }
/>
)
);
return(
<Table responsive >
<thead>
<tr>
<th>uuid</th>
<th>First</th>
<th>Last</th>
<th>email</th>
</tr>
</thead>
<tbody>{ userList }</tbody>
</Table>
);
};
export UserList = connect( mapStateToProps, mapDispatchToProps )( UserList );
export const User = ({ user, resetPasswordError, handleResetPassword }) => {
const { uuid, firstName, lastName, email } = props.user;
return (
<tr>
<td>{ uuid }</td>
<td>{ firstName }</td>
<td>{ lastName }</td>
<td>{ email }</td>
<td>
<HelpBlock disabled={ resetPasswordError ? true : false }>
{ resetPasswordError }
</HelpBlock>
<Button onClick={ () => handleResetPassword( uuid ) }>
reset password
</Button>
</td>
</tr>
);
};