I call register
, the function is executed, but it's internal dispatch
function is not executed,.
Register
import React, { Component } from "react";
import { Link, Navigate } from 'react-router-dom';
import { connect } from 'react-redux';
import { register } from '../actions/auth'
class Register extends Component {
constructor(props) {
super(props);
this.state = {
username: '',
password: '',
re_password: '',
accountCreated: false
}
}
onSubmit(e) {
e.preventDefault();
let { username, password, re_password } = this.state
if (password === re_password) {
register(username, password, re_password); <-- here
this.setState({ accountCreated: true });
}
}
render() {
if (this.state.accountCreated) {
return <Navigate to='/' />
}
return (
<div className="container mt-5">
<h1>Register for an Account</h1>
<p>Create an account with our Session Auth application</p>
<form onSubmit={(e) => this.onSubmit(e)}>
<div className="form-group">
<label htmlFor="username" className="form-label">
Username:
</label>
<input
type="text"
className="form-control"
placeholder="Username*"
name='username'
value={this.state.username}
onChange={(e) => this.setState({ username: e.target.value })}
required
/>
</div>
<div className="form-group">
<label htmlFor="password" className="form-label">
Password:
</label>
<input
type="password"
className="form-control"
placeholder="Password*"
name='password'
value={this.state.password}
onChange={(e) => this.setState({ password: e.target.value })}
minLength={6}
required
/>
</div>
<div className="form-group">
<label htmlFor="confirm_password" className="form-label">
Confirm Passeord:
</label>
<input
type="password"
className="form-control"
placeholder="Confirm Password*"
name='re_password'
value={this.state.re_password}
onChange={(e) => this.setState({ re_password: e.target.value })}
minLength={6}
required
/>
</div>
<button className="btn btn-primary mt-3" type="submit">Register</button>
</form>
<p className="mt-3">
Already have an Account? <Link to='/login'>Sign In</Link>
</p>
</div>
)
}
}
export default connect(null, { register })(Register); <-- here
file actions/auth
import axios from 'axios';
import {
REGISTER_SUCCESS,
REGISTER_FAIL
} from './types';
import Cookies from 'js-cookie';
const URL = `${process.env.REACT_APP_API_URL}`;
export const register = (username, password, re_password) => async dispatch => {
const csrftoken = Cookies.get('csrftoken');
const config = {
headers: {
'Accept': 'application/json',
'Content-Type' : 'application/json',
// 'Cache-Control' : 'no-cache'
'X-CSRFToken' : csrftoken
}
};
const body = JSON.stringify({ username, password, re_password });
try {
const res = await axios
.post(URL + '/accounts/register', body, config)
.catch((err) => console.log(err));
if (res.data.error) {
dispatch({
type : REGISTER_FAIL
});
} else {
dispatch({
type : REGISTER_SUCCESS
});
}
} catch (err) {
dispatch({
type : REGISTER_FAIL
});
}
};
file reducers/auth
import {
REGISTER_SUCCESS,
REGISTER_FAIL
} from '../actions/types';
const initilState = {
isAthenticated: null,
username: '',
first_name: '',
last_name: '',
phone: '',
city: ''
};
export default function(state = initilState, action) {
const { type, payload } = action;
switch(type) {
case REGISTER_SUCCESS:
return {
...state,
isAthenticated: false
}
case REGISTER_FAIL:
return state
default:
return state
}
};
dispatch
must be executed, information will be sent to the server and the type will be determined.
The connect
Higher Order Component injects selected state and dispatchable actions as props into the component it is decorating. In your code you are calling the register
action creator directly and not the version that was wrapped in a call to dispatch
and injected as a prop.
import React, { Component } from "react";
import { Link, Navigate } from 'react-router-dom';
import { connect } from 'react-redux';
import { register } from '../actions/auth'; // <-- register #1
class Register extends Component {
...
onSubmit(e) {
e.preventDefault();
const { username, password, re_password } = this.state;
if (password === re_password) {
register(username, password, re_password); // <-- calling register #1
this.setState({ accountCreated: true });
}
}
...
}
export default connect(null, { register })(Register); // <-- register #2
You should be calling the register
that is injected as props into the Register
component.
import React, { Component } from "react";
import { Link, Navigate } from 'react-router-dom';
import { connect } from 'react-redux';
import { register } from '../actions/auth'; // <-- register #1
class Register extends Component {
...
onSubmit(e) {
e.preventDefault();
const { username, password, re_password } = this.state;
if (password === re_password) {
this.props.register(username, password, re_password); // <-- calling register #2
this.setState({ accountCreated: true });
}
}
...
}
export default connect(null, { register })(Register); // <-- register #2