react-autosuggest
react-autosuggest copied to clipboard
Input field caret position always resets to the end of the input
The bug is testable with the Scrollable container example on http://react-autosuggest.js.org/
To reproduce:
- Focus on the input field
- Type
ac
- Place the caret between
a
andc
- Type
b
Observed behavior:
The caret jumps to the end.
Expected behavior:
The caret should stay between b
and c
.
Thanks for the issue 👍
Looks like a bug!
I guess it's probably related to alwaysRenderSuggestions
being true
, because this is the only example there that sets it to true
, and the bug is not happening in the other examples.
PR is welcome!
Getting rid of the Modal
component solves the problem; it doesn't appear to be related to alwaysRenderSuggestions
.
I've made some research on this. Like @jmlag already said, the problem is not alwaysRenderSuggestions
, i guess it is the re-rendering of the component and the inner input
element.
If the Autosuggest
uses the value
from the internal component state
, it works, but if the onChange
does propagate the newValue
to a higher order component like redux-form
in my case, ~~it does not work anymore.~~ it does not always work.
onChange=(event, { newValue, method })=> {
event.preventDefault();
const {onChange} = this.props;
onChange(newValue)
}
render(){
const {value} = this.props;
const inputProps = {
value:value
onChange:this.onChange
};
return(
<AutoSuggest
inputProps={inputProps}
suggestions={this.state.suggestions}
...
}
I am seeing this same issue using react-autosuggest with redux-form. Here's a minimal example (minus the redux store/provider boilerplate):
const SuggestComponent = ({ input }) =>
<Autosuggest
suggestions={[]}
onSuggestionsFetchRequested={() => {}}
onSuggestionsClearRequested={() => {}}
inputProps={input}
/>;
const Form = reduxForm({ form: 'foo' })(() =>
<Field name="bar" component={SuggestComponent} />
);
Rendering Form
results in an text input where the caret always jumps to the end.
Maybe worth seeing if any use of Redux (e.g. connect()) causes this behavior, or if it's just redux-form.
According to https://github.com/facebook/react/issues/955 it's react behavior
I happened to encounter this behavior recently. If your are using react-autosuggest
with redux-form
, here is a workaround for you.
Thanks to advices from https://github.com/facebook/react/issues/955
Demo
https://codesandbox.io/s/0o7wpk6ywv
Code
Wrapping react-autosuggest
in component:
class MyInput extends React.PureComponent {
state = { value: "" };
UNSAFE_componentWillReceiveProps = props => {
this.setState({ value: props.input.value });
};
onChange = (e, { newValue }) => {
e.persist();
this.setState({ value: newValue }, () => {
this.props.input.onChange(e, newValue);
});
};
render() {
const inputProps = {
...this.props.input,
value: this.state.value,
onChange: this.onChange
};
return (
<Autosuggest
suggestions={[]}
onSuggestionsFetchRequested={() => {}}
onSuggestionsClearRequested={() => {}}
inputProps={inputProps}
/>
);
}
}
And combining with redux-form
:
const SimpleForm = props => {
const { handleSubmit } = props;
return (
<form onSubmit={handleSubmit}>
<div>
<label>First Name</label>
<div>
<Field name="firstName" component={MyInput} />
</div>
</div>
</form>
);
};
export default reduxForm({
form: "simple" // a unique identifier for this form
})(SimpleForm);
This should be enough for handling change of value
with keyboard events or redux-form
's action creator (e.g. change
, initialize
, reset
...).
Remember it's still not working with normalization since normalization is a totally new transformation for the value
.
Note
UNSAFE_componentWillReceiveProps
is intentionally used here. For some unknown reasons it doesn't work with static getDerivedStateFromProps(props, state)
.
I have a very similar caret behaviour To reproduce:
Focus on the input field Type ac Place the caret between a and c delete a Observed behavior:
The caret jumps to the end.