bleepmeh
bleepmeh

Reputation: 1037

React Native TextInput does not get focus

I have this simple code of a TextInput that I want it to get focus when it first renders and on submits. However, it does not get focus at all.

render() {
    return (
      <TextInput
        ref={(c) => this._input = c}
        style={[styles.item, this.props.style]}
        placeholder={"New Skill"}
        onChangeText={(text) => {
          this.setState({text})
        }}
        onSubmitEditing={(event) => {
          this.props.onSubmitEditing(this.state.text);
          this._input.clear();
          this._input.focus();
        }}
      />
    );
  }

  componentDidMount() {
    this._input.focus();
  }

Upvotes: 14

Views: 14995

Answers (3)

Joe Rush
Joe Rush

Reputation: 137

Add this

  const inputRef: LegacyRef<TextInput> = useRef(null);
  useEffect(() => {
    if (inputRef.current) {
      setTimeout(() => {
        inputRef.current?.focus();
      }, 0);
    }
  });

Upvotes: 0

Sinapcs
Sinapcs

Reputation: 2745

You can use autoFocus property of TextInput and set it to true. It will focus TextInput on componentDidMount automatically.I tested it and it's focusing input on both componentDidMount and onSubmitEditing.

render() {
return (
  <TextInput
    ref={(c) => this._input = c}
    placeholder={"New Skill"}
    autoFocus={true}
    onChangeText={(text) => {
      this.setState({text})
    }}
    onSubmitEditing={() => {
      this.props.onSubmitEditing(this.state.text);
      this._input.clear();
      this._input.focus();
    }}
  />
);
}

Upvotes: 2

I Putu Yoga Permana
I Putu Yoga Permana

Reputation: 4220

So my assumption is true. Try to focus is failed, this._input doesn't contain anything when componentDidMount called, because render function still not called yet and no reference for it.

So the solution for now is delay it a little bit until render function already called.

Thats why wrap the code inside setTimeout function quite helpful. Anyway i admit it, it is a little bit tricky. Would be great if someone find the better way.

componentDidMount() {
   setTimeout(() => this._input.focus(), 250);
}

Upvotes: 21

Related Questions