15

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();
  }
7
  • Is it get focused or not get focused? Commented Oct 12, 2017 at 17:21
  • Oh hey sorry about my wording. I want it to get focused but it does not. Commented Oct 12, 2017 at 18:37
  • 1
    change this ref={(c) => this._input = c} to ref={(c) => { this._input = c }} and see if its gonna work Commented Oct 12, 2017 at 18:38
  • No it still does not get focused Commented Oct 12, 2017 at 20:54
  • 1
    could you try to wrap focus inside setTimeOut function like: setTimeout(() => this._input.focus(), 250); Commented Oct 13, 2017 at 3:37

3 Answers 3

22

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);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks! Your solution is the unique i found to be working. But componentDidMount() is called after the render() method, so your explanation is wrong. Also, you can set the timeout to 0 and the solution still works. I am very curious about the reason behind this behavior.
Has anyone tested this with iOS, or specifically iOS - Web... I've tried this approach and it works great for android and android - web but doesn't seem to work for iOS or iOS - web.
2

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();
    }}
  />
);
}

Comments

0

Add this

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.