Javascript 影响单击第一个按钮时所有行的处理程序
我有一个用户表,每行包含一个重置密码链接 当我单击表中的第一个按钮(每行都有该按钮)时,它会命中我的处理程序(它位于我的容器中…我的容器将处理程序作为道具传递下去),它正在命中我的处理程序Javascript 影响单击第一个按钮时所有行的处理程序,javascript,reactjs,redux,Javascript,Reactjs,Redux,我有一个用户表,每行包含一个重置密码链接 当我单击表中的第一个按钮(每行都有该按钮)时,它会命中我的处理程序(它位于我的容器中…我的容器将处理程序作为道具传递下去),它正在命中我的处理程序handleResetPassword 但是当在try/catch之后调用handleResetPassword中的setState()时,它会更新状态,这意味着我的低级组件会收到该状态的通知。因为我在更新它,说由于某种原因出现了一个错误,尽管所有行都看到了更新的状态,因此每行上的每个按钮都显示了错误。我只希望
handleResetPassword
但是当在try/catch之后调用handleResetPassword
中的setState()
时,它会更新状态,这意味着我的低级组件会收到该状态的通知。因为我在更新它,说由于某种原因出现了一个错误,尽管所有行都看到了更新的状态,因此每行上的每个按钮都显示了错误。我只希望我单击的按钮显示它,而不是全部:
UserContainer.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)
import React, { Component } from 'react'
import { HelpBlock, Button, Table } from 'react-bootstrap'
export default class Users extends Component {
render() {
return (<span><UserList {...this.props} /></span>)
}
}
export class UserList extends Component {
render(){
const { handleResetPassword, users, resetPasswordError } = this.props
const userList = users && users.map(
(user) =>
<User
handleResetPassword={handleResetPassword}
key={user.uuid}
resetPasswordError={resetPasswordError}
user={user}
/>)
return(<Table responsive >
<thead>
<tr>
<th>uuid</th>
<th>First</th>
<th>Last</th>
<th>email</th>
</tr>
</thead>
<tbody>{userList}</tbody>
</Table>)
}
}
export class User extends Component {
render() {
const { handleResetPassword } = this.props,
{ uuid, firstName, lastName, email } = this.props.user
return (
<tr>
<td>{uuid}</td>
<td>{firstName}</td>
<td>{lastName}</td>
<td>{email}</td>
<td>
<HelpBlock disabled={this.props.resetPasswordError ? true : false}>{this.props.resetPasswordError}</HelpBlock>
<Button onClick={() => handleResetPassword(uuid)}>
reset password
</Button>
</td>
</tr>
)
}
}
从'react redux'导入{connect}
从“React”导入React,{Component}
将*作为UserAsyncActions从“../actions/Users/UserAsyncActions”导入
从“../components/Users/UserList”导入用户
类UsersContainer扩展组件{
建造师(道具){
超级(道具)
此.state={
resetPasswordError:空
}
this.handleResetPassword=this.handleResetPassword.bind(this)
}
异步组件didmount(){
等待这个.props.alluser(这个.props.token)
}
异步handleResetPassword(uuid){
//console.log(e.current.target)
log(“handleResetPassword已调用!”)
试一试{
等待此消息。props.resetUserPassword()
if(this.props.hasResetPassword){
//显示成功消息(在此处设置消息)
返回
}
}
捕捉(错误){
这是我的国家({
resetEmailValidationState:“错误”,
resetPasswordError:!this.state.hasResetPassword&&“重置失败”
})
}
这是我的国家({
resetEmailValidationState:“错误”,
resetPasswordError:!this.state.hasResetPassword&&
“重置失败”
})
}
render(){
返回(
)
}
}
export const mapStateToProps=state=>({
isRequestingAllUsers:state.user.isRequestingAllUsers,
hasResetPassword:state.user.hasResetPassword,
用户:state.user.users,
令牌:state.auth.token
})
导出常量mapDispatchToProps={
allUsers:UserAsyncActions.allUsers,
resetUserPassword:UserAsyncActions.resetPasssord
}
导出{用户}
导出默认连接(mapStateToProps、mapDispatchToProps)(UsersContainer)
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)
import React, { Component } from 'react'
import { HelpBlock, Button, Table } from 'react-bootstrap'
export default class Users extends Component {
render() {
return (<span><UserList {...this.props} /></span>)
}
}
export class UserList extends Component {
render(){
const { handleResetPassword, users, resetPasswordError } = this.props
const userList = users && users.map(
(user) =>
<User
handleResetPassword={handleResetPassword}
key={user.uuid}
resetPasswordError={resetPasswordError}
user={user}
/>)
return(<Table responsive >
<thead>
<tr>
<th>uuid</th>
<th>First</th>
<th>Last</th>
<th>email</th>
</tr>
</thead>
<tbody>{userList}</tbody>
</Table>)
}
}
export class User extends Component {
render() {
const { handleResetPassword } = this.props,
{ uuid, firstName, lastName, email } = this.props.user
return (
<tr>
<td>{uuid}</td>
<td>{firstName}</td>
<td>{lastName}</td>
<td>{email}</td>
<td>
<HelpBlock disabled={this.props.resetPasswordError ? true : false}>{this.props.resetPasswordError}</HelpBlock>
<Button onClick={() => handleResetPassword(uuid)}>
reset password
</Button>
</td>
</tr>
)
}
}
import React,{Component}来自“React”
从“react bootstrap”导入{HelpBlock,Button,Table}
导出默认类用户扩展组件{
render(){
返回()
}
}
导出类UserList扩展组件{
render(){
const{handleResetPassword,users,resetPasswordError}=this.props
const userList=users&&users.map(
(用户)=>
)
返回(
uuid
弗斯特
最后
电子邮件
{userList}
)
}
}
导出类用户扩展组件{
render(){
const{handleResetPassword}=this.props,
{uuid,firstName,lastName,email}=this.props.user
返回(
{uuid}
{firstName}
{lastName}
{email}
{this.props.resetPasswordError}
handleResetPassword(uuid)}>
重置密码
)
}
}
请注意,在我单击第一个按钮后,handleResetPassword被点击,并且在该按钮中我正在设置状态:
这是我的国家({
resetEmailValidationState:“错误”,
resetPasswordError:!this.state.hasResetPassword&&
“重置失败”
})
现在,每个按钮都会显示错误消息,而不是我单击的第一个按钮:
这里有一个您控制按钮道具的状态被传递给您的
组件,然后组件将相同的道具传递给
,然后组件将相同的道具再次传递给每个
。当您单击某个按钮时,它会更改
中的状态,从而导致所有按钮中的resetPasswordError属性发生更改
您需要在容器状态中为每个按钮指定一个索引,以便单独切换,或者为每个
指定一个容器
编辑:
好的,我将使用connect为您的
创建一个容器组件。映射您的HandlerResetPassword
方法以分派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>
);
};
const-mapStateToProps=(state)=>{
返回{
用户:state.users
};
};
const mapDispatchToProps=(调度)=>{
返回{
handleResetPassword:(uuid)=>{
派遣({
键入:“重置用户密码”,
uuid
})
}
};
};
let UserList=({users,handleResetPassword})=>{
const userList=users&&users.map(
(用户)=>(
)
);
返回(
uuid
弗斯特
最后
电子邮件
{userList}
);
};
export UserList=connect(mapStateToProps,mapDispatchToProps)(UserList);
export const User=({User,resetPasswordError,handleResetPassword})=>{
const{uuid,firstName,lastName,email}=props.user;
返回(
{uuid}
{firstName}
{lastName}
{email}
{resetPasswordError