Reputation: 8189
I'm wondering at a high level what the correct pattern is for the following...
I have a HomeComponent
, with some links to other components.
When I click on one of the links, I want to make an ajax request to get the initial state for that component.
Do I dispatch
in the HomeComponent
in the onClick
? Or dispatch an action in the other components if there's no initialState
from the server? (I'm doing a universal app, so if I was to hit one of the other components directly, the initial state would already be there, but coming from my HomeComponent
, the data WON'T be there)
This is what I had so far...
class HomeComponent extends React.Component {
navigate(e) {
e.preventDefault();
// Fetch data here
actions.fetch(1234);
// When do I call this?
browserHistory.push(e.target.href);
}
render() {
const links = [
<a href="/foo/1247462" onClick={this.navigate}>Link 1</a>,
<a href="/foo/1534563">Link 2</a>,
];
return (
<ul>
{links.map((link) => (
<li>{link}</li>
))}
</ul>
);
}
}
Upvotes: 3
Views: 799
Reputation: 796
Sorry i can add a comment, is there a reason you're not using react-redux && redux-thunk ?
what you ask can be easily done with those : you fetch what you need in mapDispatchToProps & dispatch an action with the fetched initial state
Your reducer will catch the said dispatched action and update its state which will update the props of the react component with the help of mapStateToProps
I am writing from memory, it might not be accurate 100% :
redux file
componentNameReducer = (
state = {
history: ''
},
type = {}
) => {
switch(action.type) {
case 'HISTORY_FETCHED_SUCCESSFULLY':
return Object.assign({}, state, {
history: action.payload.history
});
default:
return state;
}
};
mapStateToProps = (state) => {
history: state.PathToWhereYouMountedThecomponentNameReducerInTheStore.history
};
mapDispatchToProps = (dispatch) => ({
fetchHistory : () => {
fetch('url/history')
.then((response) => {
if (response.status > 400) {
disptach({
type: 'HISTORY_FETCH_FAILED',
payload: {
error: response._bodyText
}
});
}
return response;
})
.then((response) => response.json())
.then((response) => {
//do checkups & validation here if you want before dispatching
dispatch({
type: 'HISTORY_FETCHED_SUCCESSFULLY',
payload: {
history: response
}
});
})
.catch((error) => console.error(error));
}
});
module.exports = {
mapStateToProps,
mapDispatchToProps,
componentNameReducer
}
On your react component you will need :
import React, {
Component
} from 'somewhere';
import { mapStateToProps, mapDispatachToProps } from 'reduxFile';
import { connect } from 'react-redux';
class HistoryComponent extends Component {
constructor(props){
super(props);
this.props.fetchHistory(); //this is provided by { connect } from react-redux
}
componentWillReceiveProps(nextProps){
browserHistory.push(nextProps.history);
}
render() {
return (
);
}
}
//proptypes here to make sure the component has the needed props
module.exports = connect(
mapStateToProps,
mapDispatachToProps
)(HistoryComponent);
Upvotes: 3