Instruction
We have a from:
render() {
const {handleSubmit} = this.props;
return (
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
<Field
label="Title"
name="title"
component={this.renderField}
/>
<Field
label="Categories"
name="categories"
component={this.renderField}
/>
<Field
label="Post Content"
name="content"
component={this.renderField}
/>
<button type="submit" className="btn btn-primary">Submit</button>
<Link to="/" className="btn btn-danger">Cancel</Link>
</form>
);
}
We have a function that returns a field:
renderField(field) {
const { meta: {touched, error} } = field;
const className = `form-group ${touched && error ? 'has-danger' : ''}`;
return (
<div className={className}>
<label>{field.label}</label>
<input
className="form-control"
type="text"
{...field.input}
/>
<div className="text-help">
{touched ? error : ''}
</div>
</div>
);
};
We have a validation function:
function validate(values) {
const errors = {};
// Validation
if (!values.title || values.title.length < 3) {
errors.title = "Enter a title, that is at least 3 characters!!";
}
if (!values.categories) {
errors.categories = 'Enter some categories';
}
if (!values.content) {
errors.content = 'Enter some content please';
}
//IF errors is empty, the form is fine to submit
//IF errors has *any* properties, redux form assumes form is invalid
return errors;
}
But we still do not submit anything:
onSubmit(values) {
console.log(values);
}
Now let's go to the action creator src/actions/index.js, and add new function:
import axios from 'axios'
export const FETCH_POSTS = 'fetch_posts';
export const CREATE_POST = 'create_post';
const ROOT_URL = 'http://reduxblog.herokuapp.com/api';
const API_KEY = '?key=ROOKA112';
...
export function createPost(values) {
const request = axios.post(`${ROOT_URL}/posts${API_KEY}`, values);
return {
type: CREATE_POST,
payload: request
};
}
Now, let's return to our component. And import connect from react-redux:
import {connect} from 'react-redux'
Then import our new function:
import {createPost} from "../actions/index"
And now let's combine connect and reduxForm. It was:
export default reduxForm({
validate,
form: 'PostsNewForm'
})(PostsNew);
And after changes it's like:
export default reduxForm({
validate,
form: 'PostsNewForm'
})(
connect(null, {createPost})(PostsNew)
);
Let's rewrite onSubmit:
onSubmit(values) {
this.props.createPost(values);
}
Now we send data to the server, but we do not navigate anywhere.
To tell redux to navigate somwhere is easy, just add history.push("path") to it:
onSubmit(values) {
this.props.history.push('/');
this.props.createPost(values);
}
But we need to know, if post was created, and after that navigate somewhere.
So the first thing we should do is to pass the a callback function to the method, which submits data from UI:
onSubmit(values) {
this.props.createPost(values, () => {
this.props.history.push('/');
});
}
Now, let's go to the action creator, and add promise to the function to call callback
export function createPost(values, callback) {
const request = axios.post(`${ROOT_URL}/posts${API_KEY}`, values).then(() => callback());
return {
type: CREATE_POST,
payload: request
};
}