我正在使用react-redux-firestore执行更改密码选项。如果输入的所有内容正确,则密码更改可以正常进行。如果收到任何身份验证错误,则会分派错误,并应向用户显示错误。每当收到身份验证错误时,我都会按以下方式进行处理,以在render中显示错误消息
{authError ? this.openSnackbar({ message: '{authError}' }) : null}
但这会造成无限循环。
稍后添加了componentDidMount()方法。这样可以防止循环通过,但无法显示错误消息。
componentDidMount = () => {
const { authError } = this.props;
console.log(authError)
if (authError) {
this.setState(
{
loading: false,
message: '{authError}',
open: true
},
() => {
alert(this.state.open);
}
)
}
};
当我执行console.log(authError)..时,它没有显示错误消息。
在按钮上单击如何显示错误消息?
任何帮助。
更改密码组件
import React, { Component } from 'react'
import { Redirect } from 'react-router-dom'
import IconButton from '@material-ui/core/IconButton';
import { connect } from 'react-redux'
import { compose } from 'redux'
import { changePassword } from '../../store/actions/auth'
const styles = {
textField: {
fontSize: '5px'
},
};
class ChangePassword extends Component {
constructor(props) {
super(props);
this.state = {
loading: false,
open: false,
message: '',
cp_currentPassword: '',
cp_newPassword: '',
cp_confirmPassword: ''
}
}
componentDidMount = () => {
const { authError } = this.props;
console.log('did mount called')
console.log(authError)
if (authError) {
this.setState(
{
loading: false,
message: '{authError}',
open: true
},
() => {
alert(this.state.open);
}
)
}
};
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value
})
}
openSnackbar = ({ message }) => {
this.setState({
open: true,
message
});
};
handleSubmit = (e) => {
e.preventDefault();
let curpass = this.state.cp_currentPassword
let newpass = this.state.cp_newPassword
this.setState({ loading: true });
this.props.changePassword(curpass, newpass, this.passwordUpdated)
}
passwordUpdated = () => {
this.setState({
message: 'Password changed Successfully.!',
open: true,
loading: false
});
};
render() {
const { classes, auth, authError } = this.props;
console.log(authError)
const { loading } = this.state;
const message = (
<span
id="snackbar-message-id"
dangerouslySetInnerHTML={{ __html: this.state.message }}
/>
);
if (!auth.uid) return <Redirect to='/signin' />
return (
<div>
{/* {authError ? this.openSnackbar({ message: '{authError}' }) : null} */}
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<Card>
<CardHeader color="warning">
<h4 className={classes.cardTitleWhite}>Change Password</h4>
</CardHeader>
<form >
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<CardBody>
<GridContainer>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_currentPassword"
label="Current Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_currentPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_newPassword"
label="New Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_newPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<TextField
id="cp_confirmPassword"
label="Confirm Password"
type="password"
fullWidth
className={classes.textField}
value={this.state.cp_confirmPassword}
onChange={this.handleChange}
margin="normal"
required={true}
/>
</GridItem>
</GridContainer>
</CardBody>
<CardFooter>
<Button color="warning" onClick={(e) => this.handleSubmit(e)} disabled={loading}>
{loading && <CircularProgress style={{ color: 'white', height: '20px', width: '20px', marginRight: '10px' }} />}
Change Password
</Button>
</CardFooter>
</GridItem>
</GridContainer>
</form>
</Card>
</GridItem>
</GridContainer>
<Snackbar
open={this.state.open}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
message={message}
variant="error"
onClose={() => this.setState({ open: false, message: '' })}
action={
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={() => this.setState({ open: false, message: '' })}
>
<CloseIcon className={classes.icon} />
</IconButton>
}
autoHideDuration={3000}
/>
</div>
)
}
}
const mapstateToProps = (state) => {
return {
auth: state.firebase.auth,
authError: state.authroot.autherr
}
}
const mapDispatchtoProps = (dispatch, getState) => {
return {
changePassword: (currentPassword, newPassword, passwordUpdated) => { dispatch(changePassword(currentPassword, newPassword, passwordUpdated)) }
}
}
export default compose(
withStyles(styles),
connect(mapstateToProps, mapDispatchtoProps)
)(ChangePassword);
身份验证操作
export const changePassword = (currentPassword, newPassword, func) => {
return (dispatch, getState, { getFirebase }) => {
const firebase = getFirebase();
var user = firebase.auth().currentUser;
var cred = firebase.auth.EmailAuthProvider.credential(
user.email, currentPassword);
// reauthenticateAndRetrieveDataWithCredential
user.reauthenticateWithCredential(cred)
.then(() => {
user.updatePassword(newPassword).then(() => {
console.log("Password updated!");
func();
}).catch((error) => { dispatch({ type: 'CHANGEPASSWORD_ERR', error }) });
}).catch((error) => {
dispatch({ type: 'CHANGEPASSWORD_CURRPSW_ERR', error })
});
}
}
auth reducer
case 'CHANGEPASSWORD_SUCCESS':
return {
...state,
//action.func
};
case 'CHANGEPASSWORD_CURRPSW_ERR':
return {
...state,
autherr: action.error.message
};
case 'CHANGEPASSWORD_ERR':
return {
...state,
autherr: action.error.message
};
答案 0 :(得分:0)
只需像这样的道具直接设置Snackbar组件的打开道具,
<Snackbar
open={!!this.props.authError}
anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
message={message}
variant="error"
onClose={() => this.setState({ open: false, message: '' })}
action={
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={() =>{have a action dispatch for clear error added into the reducer}}
>
<CloseIcon className={classes.icon} />
</IconButton>
}
autoHideDuration={3000}
/>
答案 1 :(得分:-1)
我认为您要实现的目标不是与道具相关,而是与状态相关(传递给props
的Redux状态)。状态更改时,您希望弹出错误。在这种情况下,您应该使用componentDidUpdate
而不是componentDidMount
,因为后者在组件安装时只会运行一次。
componentDidUpdate = (prevProps) => {
const { authError } = this.props;
console.log(authError)
if (authError != prevProps.authError) {
this.setState(
{
loading: false,
message: authError,
open: true
},
() => {
alert(this.state.open);
}
)
}
};