我有一个使用Redux的SignUp组件,我将如何使用容器来分隔Redux逻辑(例如mapStateToProps等)以最小化SignUp组件中的代码。我听说过使用高阶组件,但是我想首先看看是否可以将一些业务逻辑抽象到容器中。
SignUp.js
import React, { Component } from 'react';
import Grid from '@material-ui/core/Grid';
import PropTypes from 'prop-types';
import Typography from '@material-ui/core/Typography';
import { registerUser } from '../actions/authActions';
import SignUpForm from './SignUpForm/SignUpForm';
import ReduxContainer from '../reduxHOC';
class SignUp extends Component {
constructor() {
super();
this.state = {
formData: {
email: '',
username: '',
password: '',
passwordConf: '',
isAuthenticated: false,
},
password_error_text: '',
errors: {},
passErr: null,
passwordConf_error_text: '',
passwordConfpassErr: null,
};
}
componentDidMount() {
// console.log(this.props.auth);
if (this.props.auth.isAuthenticated) {
this.props.history.push('/dashboard');
}
}
// this line is magic, redirects to the dashboard after user signs up
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push('/dashboard');
}
if (nextProps.errors) {
this.setState({ errors: nextProps.errors });
}
}
handleUsername= (e) => {
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
username: e.target.value,
},
});
}
handleEmail= (e) => {
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
email: e.target.value,
},
});
}
handlePassword = (e) => {
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
password: e.target.value,
},
});
}
handlePasswordConf = (e) => {
e.preventDefault();
const { formData } = this.state;
this.setState({
formData: {
...formData,
passwordConf: e.target.value,
},
});
}
handleSubmit = (e) => {
e.preventDefault();
const { formData } = this.state;
const {
username, email, password, passwordConf,
} = formData;
this.setState({
username: this.state.username,
password: this.state.password,
passwordConf: this.state.passwordConf,
email: this.state.email,
});
const creds = {
username,
email,
password,
};
console.log(creds);
if (password === passwordConf) {
this.props.registerUser(creds, this.props.history);
} else {
this.setState({ passErr: "Passwords Don't Match" });
}
}
componentDidUpdate(prevProps, prevState) {
if (this.state.formData.password.length !== prevState.formData.password.length) {
if (this.state.formData.password.length <= 6) {
this.setState({
passErr: true,
password_error_text: 'Password must be at least 6 Chars',
});
console.log(this.state.password_error_text);
} else {
this.setState({
passErr: false,
password_error_text: '',
});
}
}
}
render() {
// debugger;
// console.log(this.state.formData.password)
// console.log(this.state.password_error_text)
// here we are making sure all fields are filled before we allow the button to appear
return (
<div>
<Grid container justify="center" spacing={0}>
<Grid item sm={10} md={6} lg={4} style={{ margin: '20px 0px' }}>
<Typography variant="h4" style={{ letterSpacing: '2px' }}>
Sign Up
</Typography>
{this.props.auth.errors ? (
this.props.auth.errors.map((err, i) => (
<div key={i} style={{ color: 'red' }}>
{err}
</div>
))
) : (
null
)}
{this.state.passErr && (
<div style={{ color: 'red' }}>
{this.state.passErr}
</div>
)}
<SignUpForm
signSubmit={this.handleSubmit}
username={this.state.username}
usernameChange={this.handleUsername}
email={this.state.email}
handleEmail={this.handleEmail}
password_error_text={this.state.password_error_text}
passErr={this.state.passErr}
password={this.state.password}
handlePassword={this.handlePassword}
passwordConf_error_text={this.state.passwordConf_error_text}
passwordConfpassErr={this.state.passwordConfpassErr}
passwordConf={this.state.passwordConf}
handlePasswordConf={this.handlePasswordConf}
validation={validation.validation}
/>
</Grid>
</Grid>
</div>
);
}
}
SignUp.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
};
const mapStateToProps = state => ({
auth: state.auth,
});
const mapDispatchToProps = dispatch => ({
registerUser: userData => dispatch(registerUser(userData)),
});
export default ReduxContainer(SignUp, mapStateToProps, mapDispatchToProps);
注意:ReduxContainer是一个高阶组件,其目的是防止我在各处使用redux connect。
答案 0 :(得分:1)
有两种方法:
方法1:
首先删除用于ReduxContainer
方法的所有Redux道具。
第二步::在您的src
文件夹中,创建一个名为containers
的floder,在其中的文件SignUp.js
将引用您的与其连接的组件SignUp
是Redux store
。为此,SignUp
组件应导出为:export default SignUp
第三:在该文件中应该有:
import SignUp from '../components/SignUp';
import { connect } from 'redux-think';
const mapStateToProps = state => ({
auth: state.auth,
});
const mapDispatchToProps = dispatch => ({
registerUser: userData => dispatch(registerUser(userData)),
});
export default connect(mapStateToProps, mapDispatchToProps)(SignUp);
这样,您将不需要挂钩,这是构建React / Redux应用程序的一种模式。
方法2:
src/components/SignUp.js
那样隐式地注册,而应将其移动为src/components/signup/SignUp.js
index.js
中创建signup
文件,并在其中上面的容器中添加逻辑,并对导入组件的路径进行编辑:import SignUp from './SignUp'
< / li>