我是新来的React和react-redux。我目前正在根据这篇很棒的文章https://medium.com/@l_e/writing-a-wizard-in-react-8dafbce6db07做一个用户注册向导,并做了一些修改。
这里是RegisterWizard
组件:
import React from 'react';
import { connect } from 'react-redux';
import { Step1 } from './Step1'
import { Step2 } from './Step2'
class RegisterWizard extends React.Component {
constructor(props){
super(props);
this.state = {
currentStep: 1,
user: {
full_name: '',
email: '',
phone_number: '',
password: '',
confirm_password: ''
}
};
this._next = this._next.bind(this);
}
_next(data) {
let { user, currentStep } = this.state;
let { full_name, phone_number, password, confirm_password } = data;
if (currentStep >= 1) {
currentStep = 2;
} else {
currentStep = currentStep + 1;
}
this.setState({
currentStep: currentStep
});
if (full_name) {
this.setState({
user: {
...user,
full_name
}
});
}
if (phone_number) {
this.setState({
user: {
...user,
phone_number
}
});
}
if (password) {
this.setState({
user: {
...user,
password
}
});
}
if (confirm_password) {
this.setState({
user: {
...user,
confirm_password
}
});
}
}
render() {
console.log(this.state.user)
const { currentStep } = this.state;
return(
<div className="block-center mt-4 wd-xl">
<div className="card card-flat">
<Step1 currentStep={currentStep} afterValid={this._next} />
<Step2 currentStep={currentStep} afterValid={this._next} />
</div>
</div>
);
}
}
const connectedRegisterWizard = connect(null, null)(RegisterWizard);
export { connectedRegisterWizard as RegisterWizard };
这里是Step 1
组件。我正在通过API处理我的验证
import React from 'react';
import { connect } from 'react-redux';
import { Input } from 'reactstrap';
import { userActions } from './../../../_actions';
class Step1 extends React.Component {
constructor(props) {
super(props);
this.state = {
full_name: ''
}
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
const { name, value } = event.target;
this.setState({
...this.state,
[name]: value
});
}
handleSubmit(event) {
event.preventDefault();-
const { full_name } = this.state;
const { dispatch } = this.props;
const names = full_name.split(" ");
const [first_name, last_name, ...other_names] = names
this.setState({
...this.state,
submitted: true
});
dispatch(userActions.register({
...this.state,
first_name: first_name ? first_name : '',
last_name: last_name ? last_name : '',
other_names: other_names ? other_names.join(" ") : '',
}));
// I want to get the new formErrors from props after the above
}
_validate() {
/*Only call this after a check is mad to make sure
that there are no errors for first_name */
let { full_name } = this.state
this.props.afterValid({
full_name
})
}
render() {
if (this.props.currentStep !== 1) {
return null;
}
const { full_name } = this.state;
const { requesting, formErrors, alert } = this.props;
return(
<div>
<div className="card-header text-center bg-info">
<p className="text-center py-2">What is your full name?</p>
</div>
<div className="card-body">
<form className="mb-3" onSubmit={this.handleSubmit}>
<div className='form-group'>
<label className="text-muted" htmlFor="full_name">Full Name</label>
<div className="input-group with-focus">
<div className="input-group-prepend">
<span
className="input-group-text text-muted border-right-0">
<em className="fa fa-user"></em>
</span>
</div>
<Input type="text" className="border-left-0" name="full_name"
value={full_name} onChange={this.handleChange}/>
{
formErrors.map((error, i) =>
error.pointer == 'first_name' &&
<span key={i} className="invalid-feedback">{ error.message }</span>
)
}
</div>
</div>
<button className="btn btn-block btn-primary mt-3"
type="submit">Next</button>
</form>
</div>
</div>
);
}
}
function mapStateToProps(state) {
const { alert } = state;
const { requesting, formErrors } = state.registration;
return {
requesting,
formErrors,
alert,
};
}
const connectedStep1 = connect(mapStateToProps)(Step1);
export { connectedStep1 as Step1 };
这是register
中的userActions.js
函数
function register(user) {
return dispatch => {
dispatch(request(user));
dispatch(alertActions.clear());
userService.register(user)
.then(
user => {
dispatch(success());
dispatch(alertActions.success('Success! Please click on the activation link '
+ 'sent to your email in order to login'));
},
error => {
const parsedError = errorHandler(error);
const {alertError} = parsedError;
if (alertError) {
dispatch(alertActions.error(alertError))
}
dispatch(failure(parsedError));
}
);
};
function request(user) { return { type: userConstants.REGISTER_REQUEST, user } }
function success(user) { return { type: userConstants.REGISTER_SUCCESS, user } }
function failure(error) { return { type: userConstants.REGISTER_FAILURE, error } }
}
这是register
中的userService.js
函数
function register(user) {
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(user)
};
return fetch(`${config.apiUrl}/api/auth/register/`, requestOptions).then(handleResponse);
}
这里是regiStrationReducer.js
import { userConstants } from '../_constants';
const initialState = {
requesting: false,
formErrors: []
}
export function registration(state = initialState, action) {
switch (action.type) {
case userConstants.REGISTER_REQUEST:
return {
...state,
requesting: true
};
case userConstants.REGISTER_SUCCESS:
return {
...state,
requesting: false,
formErrors: []
};
case userConstants.REGISTER_FAILURE:
return {
...state,
requesting: false,
formErrors: action.error.formErrors
};
default:
return state
}
}
仅当_validate()
没有格式错误时,我才希望调用方法first_name
,因此我想在执行以下命令后获取新的formErrors
:
dispatch(userActions.register({
...this.state,
first_name: first_name ? first_name : '',
last_name: last_name ? last_name : '',
other_names: other_names ? other_names.join(" ") : '',
}));
当我提交表单时,将向userActions.register()
进行调度。如何从道具中获得新的formErrors
?
答案 0 :(得分:0)
我找到了解决方案。我使用了componentDidUpdate
。我做了
componentDidUpdate(prevProps) {
if (this.props.formErrors != prevProps.formErrors) {
let { formErrors } = this.props;
let { submitted } = this.state;
let pointers = formErrors.map(error => error.pointer);
if (pointers.indexOf('first_name') == -1 && submitted) {
this._validate();
}
}
}