Reputation: 5210
the problem I'm running into is Actions must be plain objects
when passing data through my action creators. Basically I'm trying to capture user input through the click of a button, and based on what button (view) is clicked the event.target.innerHTML
is passed to the action creator fetchDataAsync(view)
which then performs a GET request via axios and dispatches based on what view was selected.
I'm still new with Redux, though, and I'm unsure of what I'm doing wrong here. I've seen an async action performed inside an action creator before...
Component connected with Redux:
class ViewSelector extends Component {
selectView(event) {
this.props.fetchDataAsync(event.target.innerHTML);
}
render() {
return (
<nav>
<button onClick={this.selectView.bind(this)}>VIEW ALL</button>
<button onClick={this.selectView.bind(this)}>VIEW LAST WEEK</button>
<button onClick={this.selectView.bind(this)}>VIEW LAST MONTH</button>
</nav>
);
}
}
function mapStateToProps(state) {
return {
view: state.view
};
}
export default connect(mapStateToProps, actions)(ViewSelector);
Action creator for dispatching based on event.target.innerHTML
:
export function fetchDataAsync(view) {
return dispatch => {
dispatch(fetchData());
axios.get(DATA_URL)
.then(res => {
dispatch(fetchDataSuccess(res.data));
if (view == 'VIEW LAST WEEK') {
dispatch(lastWeekData(res.data));
} else if (view == 'VIEW LAST MONTH') {
dispatch(lastMonthData(res.data));
}
}).catch(err => {
dispatch(fetchDataFailure(err));
});
};
}
Any advice is appreciated. Or if you believe there's a more effective way of capturing that user input and passing it to an action creator...I'd be curious to hear more!
Upvotes: 0
Views: 5615
Reputation: 1262
The general idea that you have above is correct. In the React component, you want to isolate the information that is relevant for the async function and call the action-creator with that information. The action creator can make an XHR call, and then dispatch actions accordingly.
(I am assuming that you have middleware installed, otherwise do look at something like redux-thunk
to get started. The middleware helps connect the dots in this case, making sure async actions and results are dispatched appropriately).
Without knowing too much about the lastWeekData
, lastMonthData
, etc, I would only suggest possibly simplifying the 'then' part of the call. If there is any special logic, it conventionally belongs in the reducer.
Upvotes: 1
Reputation: 836
You need to install redux-thunk to use async action. And then create your store like this
import thunk from 'redux-thunk';
const store = createStore(YOURREDUCER, applyMiddleware(thunk));
Upvotes: 3