React-autosuggest: Input field caret position always resets to the end of the input

Created on 12 Jul 2017  路  7Comments  路  Source: moroshko/react-autosuggest

The bug is testable with the Scrollable container example on http://react-autosuggest.js.org/

To reproduce:

  1. Focus on the input field
  2. Type ac
  3. Place the caret between a and c
  4. Type b

Observed behavior:

The caret jumps to the end.

Expected behavior:

The caret should stay between b and c.

bug help wanted

Most helpful comment

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).

All 7 comments

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

approots picture approots  路  14Comments

jchapelle picture jchapelle  路  10Comments

tgaff2x picture tgaff2x  路  11Comments

thibaudcolas picture thibaudcolas  路  15Comments

JamieDixon picture JamieDixon  路  10Comments