How do I update the horse listing after the add horse action is fully done?
I think that the reloadHorseList in CreateHorse is running before createHorse actions is completely done so sometimes I see new horse in list and sometimes not. A full reload shows an update always.
Horses Component
...
import { getHorses } from '../../actions';
import ListHorses from './ListHorses';
import CreateHorse from './forms/createHorseForm';
class Horses extends React.Component {
constructor(props) {
super(props);
this.state = {
...
};
this.reloadHorseList = this.reloadHorseList.bind(this);
}
componentDidMount() {
this.reloadHorseList();
}
reloadHorseList() {
this.props.getHorses(this.props.current_user.selected_stable);
}
render() {
return (
<div className="content page-content-wrapper1">
<CreateHorse
current_user={this.props.current_user}
reloadHorseList={this.reloadHorseList}
/>
<ListHorses
current_user={this.props.current_user}
horses={this.props.horses}
/>
</div>
);
}
}
function mapStateToProps(state) {
return {
horses: state.horses
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
getHorses: getHorses
},
dispatch
);
}
export default connect(mapStateToProps, mapDispatchToProps)(Horses);
Create Horse Form
...
import { Field, reduxForm, getFormValues } from 'redux-form';
import {
createHorse,
getHorseSelect,
updateHorseCount
} from '../../../actions';
import { connect } from 'react-redux';
const renderField = (...
);
class CreateHorse extends Component {
constructor(props) {
super(props);
this.state = {
...
};
this.setMessage = this.setMessage.bind(this);
}
onSubmit(props) {
//let p = this.props.reloadHorseList;
try {
this.props.createHorse(props, this.setMessage);
//running before I have finished creating my horse
this.props.reloadHorseList();
} catch (err) {
...
}
}
render() {
const { handleSubmit } = this.props;
return (
<div>
...
{this.state.displayHorseCreateForm && (
<div>
<h4 className="header-content">Add Horse</h4>
<p> * required field</p>
<form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
// fields here
<button type="submit" className="btn btn-primary">
Submit
</button>
</form>
</div>
)}
</div>
);
}
}
function validate(values) {
...
}
function mapStateToProps(state) {
---
}
export default connect(mapStateToProps, {
createHorse,
getHorseSelect,
updateHorseCount
})(
reduxForm({
form: 'HorseCreatetForm',
initialValues: {
...
},
validate
})(CreateHorse)
);
//create horse action
export const createHorse = (props, setMessage) => async dispatch => {
try {
const request = await axios.post(`/api/horse/create`, props);
return {
type: CREATED_HORSE,
payload: request.data
};
} catch (err) {
...
}
};
ListHorses
...
import { deleteHorse } from '../../actions';
class HorsesList extends React.Component {
render() {
let horses = this.props.horses;
let horseCount = this.props.horse_count;
return (
<div className="content">
horse count: {horseCount}
<ul className="list-inline box-body">
{horseCount > 0 &&
horses.map((horse, key) => (
<li key={key}>
...//listing here
</li>
))}
</ul>
</div>
);
}
}
function mapStateToProps(state) {
return {
horse_count: state.horse_count
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
...
},
dispatch
);
}
export default connect(mapStateToProps, mapDispatchToProps)(HorsesList);
The solution that worked for me is to send a callback to the CreateHorse component to send to the createHorse action which runs Horse components action to getHorses.
class Horses extends React.Component {
constructor(props) {
super(props);
this.state = {
horses: this.props.horses,
};
this.reloadHorses = this.reloadHorses.bind(this);
}
componentDidMount(prevProps) {
this.props.getHorses(this.props.current_user.selected_stable);
}
reloadHorses = () => {
this.props.getHorses(this.props.current_user.selected_stable);
};
...
<CreateHorse
current_user={this.props.current_user}
reloadHorses={this.reloadHorses}
/>
<ListHorses
horses={this.props.horses}
/>
...
function mapStateToProps(state) {
return {
horses: state.horses
};
}
function mapDispatchToProps(dispatch) {
return bindActionCreators(
{
getHorses: getHorses
},
dispatch
);
}
export default connect(mapStateToProps, mapDispatchToProps)(Horses);
then in CreateHorse component
onSubmit(props) {
this.props.createHorse(props, this.setMessage, this.props.reloadHorses);
}
}
Then in the createHorse action
export const createHorse = (
props,
setMessage,
reloadHorses
) => async dispatch => {
try {
const request = await axios.post(`/api/horse/create`, props);
reloadHorses();
return {
type: CREATED_HORSE,
payload: request.data
};
} catch (err) {
...
}
};