我正在使用React,Redux,NodeJS和ExpressJS。我还在前端使用material-ui。我创建了一个对话框,用户可以在其中输入信息和注册。用户单击“提交”后,便发出了帖子要求。返回的任何错误都将被置于状态中的errors对象中。如果返回了任何错误(例如密码不匹配),则会在输入字段下方列出。如果单击了提交按钮,并且没有错误,则对话框保持打开状态。如果没有错误返回,我将如何关闭对话框(state.open应该设置为false)。我该怎么做。这是我的代码:
authActions.js:
export const registerUser = (userData, history) => dispatch => {
axios
.post("/api/users/register", userData)
.then(res => history.push("/signup/done"))
.catch(err =>
dispatch({
type: GET_ERRORS,
payload: err.response.data
})
);
};
signup.js:
class SignUpD extends Component {
constructor() {
super();
this.state = {
open: false,
username: "",
email: "",
password: "",
password2: "",
errors: {}
};
this.onChange = this.onChange.bind(this);
this.onSubmit = this.onSubmit.bind(this);
}
componentDidMount() {
if (this.props.auth.isAutenticated) {
this.props.history.push("/");
}
}
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
this.setState({ errors: nextProps.errors });
}
}
handleClickOpen = () => {
this.setState({ open: true });
};
handleClose = () => {
this.setState({ open: false, errors: {} });
};
onChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
onSubmit(e) {
e.preventDefault();
const newUser = {
username: this.state.username,
email: this.state.email,
password: this.state.password,
password2: this.state.password2
};
this.props.registerUser(newUser, this.props.history);
}
render() {
const { errors } = this.state;
return (
<div>
<ListItem
button
style={{ paddingTop: 60, top: 0 }}
onClick={this.handleClickOpen}
>
<ListItemText primary="Sign Up" />
</ListItem>
<Dialog
fullWidth
open={this.state.open}
onClose={this.handleClose}
aria-labelledby="form-dialog-title"
style={{ width: "100" }}
>
<DialogTitle id="form-dialog-title">Register</DialogTitle>
<DialogContent>
<DialogContentText>
Enter registration details here
</DialogContentText>
<TextField
margin="dense"
name="email"
label="Email Address"
value={this.state.email}
fullWidth
onChange={this.onChange}
/>
{errors.email && <div style={{ color: "red" }}>{errors.email}</div>}
<TextField
margin="dense"
name="username"
label="Username"
type="text"
value={this.state.username}
fullWidth
onChange={this.onChange}
/>
{errors.username && (
<div style={{ color: "red" }}>{errors.username}</div>
)}
<TextField
margin="dense"
name="password"
label="Password"
type="password"
value={this.state.password}
fullWidth
onChange={this.onChange}
/>
{errors.password && (
<div style={{ color: "red" }}>{errors.password}</div>
)}
<TextField
margin="dense"
name="password2"
label="Enter Password Again"
value={this.state.password2}
type="password"
fullWidth
onChange={this.onChange}
/>
{errors.password2 && (
<div style={{ color: "red" }}>{errors.password2}</div>
)}
</DialogContent>
<DialogActions>
<Button onClick={this.handleClose} color="primary">
Cancel
</Button>
<Button onClick={this.onSubmit} color="primary">
Register
</Button>
</DialogActions>
</Dialog>
</div>
);
}
}
SignUpD.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
errors: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
errors: state.errors
});
export default connect(
mapStateToProps,
{ registerUser }
)(withRouter(SignUpD));
如果您需要任何澄清或有任何疑问,请与我联系。预先感谢。
答案 0 :(得分:2)
使用redux store
而不是使用组件的本地状态来确定是否应打开对话框。这样,您可以调用操作以从任何地方更新商店,从而控制对话框是否打开。
与在mapDispatch中为道具定义registerUser
的方式相同,您可以定义另一个动作,该动作可以分配类似{type:'OPEN_DIALOG'}
的东西,然后在化简器中,您可以通过设置来响应OPEN_DIALOG
事件state.dialogIsOpen
为真。然后,在您的mapStateToProps
中,确保要包含来自Redux状态的dialogIsOpen
。并将使用this.state.dialogIsOpen
的任何地方更改为this.props.dialogIsOpen