Reputation: 445
I have a component where user enters a name, which on changing requires two actions to be taken:
I am using thunk middleware for doing the async work, and then dispatching both actions inside the thunk action creator.
But upon passing actions to dispatch in the thunk action creator, only the action dispatched last reaches the reducer (and hence able to update the state). Why is this so? Where am I making the mistake?
Thank you for your answers!
Relevant code snippets are:
namesection.js
function NameSection({
entityType,
nameValue,
onNameChange,
warnIfExists
}) {
return (
<div>
<form>
<Row>
<Col md={6} mdOffset={3}>
<NameField
defaultValue={nameValue}
warn={warnIfExists}
onChange={onNameChange}
/>
</Col>
</Row>
</form>
</div>
);
}
function mapStateToProps(rootState) {
const state = rootState.get('nameSection');
return {
nameValue: state.get('name'),
warnIfExists: state.get('warnIfExists')
};
}
function mapDispatchToProps(dispatch, {entityType}) {
return {
onNameChange: (event) =>
dispatch(handleNameChange(event.target.value, entityType)),
};
}
export default connect(mapStateToProps, mapDispatchToProps)(NameSection);
action.js
export function handleNameChange(
newName,
entityType
) {
return (dispatch) => {
dispatch({
meta: {debounce: 'keystroke'},
payload: newName,
type: UPDATE_NAME_FIELD
});
return request.get('/search/exists')
.query({
collection: entityType,
q: newName
})
.then(res => dispatch({
meta: {debounce: 'keystroke'},
payload: res.text === 'true',
type: UPDATE_WARN_IF_EXISTS
}))
.catch((error: {message: string}) => error);
};
}
reducer.js
function reducer(
state = Immutable.Map({
name: '',
warnIfExists: false
}),
action
) {
const {payload, type} = action;
console.log('reducer', payload, type);
switch (type) {
case UPDATE_NAME_FIELD:
return state.set('name', payload);
case UPDATE_WARN_IF_EXISTS:
return state.set('warnIfExists', payload);
// no default
}
return state;
}
In this case, only warnIfExists is updated, while name field is not update.
Upvotes: 1
Views: 249
Reputation: 2925
Debouncing the entire keypress event handler doesn't seem like a good idea somehow. Doesn't this also block the characters from showing up right away?
Have you tried splitting this in two actions?
UPDATE_NAME_FIELD
should always be dispatched and change the state immediately.CHECK_UNIQUE_NAME
is dispatched from the same event handler, but is debounced, and then you retrieve the current value from getState before making an api request. Then this would result in CHECK_UNIQUE_NAME_SUCCESS
, where the reducer handles the result, but also checks if the name has changed in the meantime (so that api responses for old values don't corrupt the state).Upvotes: 0