I am dynamically creating list of inputs with React and Redux. After clicking a button an input is added to the end of list. I need to focus last added input. I tried this code but it focuses penultimate input
const mapDispatchToProps = (dispatch, ownProps) => ({
onOptionsChange: (newOptions) => {
dispatch(formActions.updateOptions(newOptions));
}
});
...
this.props.onOptionsChange({ ...this.props, inputsList}); // change list of inputs
ReactDOM.findDOMNode(this.inputs[this.props.choices.length - 1]).focus();
In logs I can see that focus() is executed before props from state are updated. How can I wait for dispatch to finish?
Promisify your dispatch
Lets write a middleware that returns a promise after completing the dispatch.
const thenMiddleware = store => next => action => {
return new Promise((resolve, reject) => {
try {
resolve(next(action));
} catch(e) {
reject(e);
}
})
};
Prepare your store first, by installing the middleware
import { createStore, applyMiddleware } from 'redux';
import rootReducer from './reducers/index';
/**
* Our star of the show
*/
const thenMiddleware = store => next => action => {
return new Promise((resolve, reject) => {
try {
resolve(next(action));
} catch(e) {
reject(e);
}
})
};
const store = createStore(
rootReducer,
applyMiddleware(thenMiddleware)
);
Now we have to return the dispatch inside our mapDispatchToProps method
const mapDispatchToProps = (dispatch, ownProps) => ({
onOptionsChange: (newOptions) => {
return dispatch(formActions.updateOptions(newOptions));
}
});
Finally hook your event on complete
Now that you know which input you created last time, you can attach an on complete function to this dispatch.
this.props.onOptionsChange(newOptions).then(() => {
// do your input focusing here
});
I would implement componentDidUpdate
and check the length of your "input-array" or whatever data-structure you are using:
componentDidUpdate(prevProps, prevState) {
if (prevProps.choices.length < this.props.choices.length) {
ReactDOM.findDOMNode(this.inputs[this.props.choices.length - 1]).focus();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With