37
votes

Working through the Redux AddTodo example in React Native. The first AddTodo example below uses state to store the TextInput value and works fine.

class AddTodo extends React.Component{

    constructor(props){
        super(props);
        this.state = { todoText: "" }; 
    }
    update(e){
        if(this.state.todoText.trim()) this.props.dispatch(addTodo(this.state.todoText)); 
        this.setState({todoText: "" }); 
    }
    render(){
        return(
            <TextInput 
                value = {this.state.todoText}
                onSubmitEditing = { (e)=> { this.update(e); } }
                onChangeText = { (text) => {this.setState({todoText: text}) } } />
        );
    }
}

However following a few of the Redux examples, the following code is much shorter and also works except that the TextInput value is not cleared after submitting

let AddTodo = ({ dispatch }) => {

  return (
      <TextInput 
          onSubmitEditing = { e => { dispatch(addTodo(e.nativeEvent.text)) } } 
      />
  )
}

Is there any way I can clear the InputText value from onSubmitEditing?

18

18 Answers

89
votes

Add ref to your TextInput, for example:

 <TextInput ref={input => { this.textInput = input }} />

then call this.textInput.clear() to clear your input value

23
votes

For iOS, it will give the default clear text button.

<TextInput clearButtonMode="always" />

See the doc

16
votes

According to changes and recommendations after React 16.3, you will need to retrieve the ref at your constructor using React.createRef:

At constructor function: this.myTextInput = React.createRef();

At render function:

<TextInput ref={this.myTextInput} />

And then you can call

this.myTextInput.current.clear();

[1] https://reactjs.org/docs/refs-and-the-dom.html

10
votes

I am using Native base and here is how i have made it work

constructor(props) {
    super(props);
    this.searchInput = React.createRef();
}

<Input
    placeholder="Search"
    ref={this.searchInput}
/>

then whenever i want to clear i use

    this.searchInput.current._root.clear();

reference https://github.com/facebook/react-native/issues/18843

6
votes

One simpler approach will be to use the value property of TextInput and use the component's state value object to set the value of textInput.

state = {
   inputTextValue : '',
}

submitText = () => {
    //handle the click action

    //add this line at the end of the function after you are done handling with the input text value.
     setState({inputTextValue : ''})
}  

<TextInput 
       onChangeText={(text) => this.setState({ inputText: text })}
       placeholder="Monday's breakfast"
       value={this.state.inputTextValue}
 />
 <TouchableOpacity 
       onPress={() => this.submitText()}>
       <Text>Submit</Text>
 </TouchableOpacity>
2
votes

this works for me

  ref={element => {  
          //Clear text after Input
                this.attendee = element
              }}
              onSubmitEditing={this.handleAddPress}

and this.attendee.setNativeProps({ text: '' }) //Clear text after Input

2
votes

Following code sample:

<TextInput 
    onChangeText={(text) => this.onChangeText(text)} 
    ref={component => this._textInput = component}
    onSubmitEditing={() => {
       this.clearText()
     }}
/>

clearText(){
  this._textInput.setNativeProps({ text: ' ' });

  setTimeout(() => {
    this._textInput.setNativeProps({ text: '' });
   },3);
}
2
votes

This worked for me..

Init myTextInput at the constructor:

this.myTextInput = React.createRef();

Add the reference at render function:

<Input ref={this.myTextInput} />

And then you can call

this.myTextInput.current.value='';
2
votes

Because you're using a functional component you can use Hooks as follows. If you have conditional renders your code check that todoInput is defined in the function passed to useEffect. I assumed your state variable is called todoText in the dependency list.

import {useRef, useEffect} from 'react';


let AddTodo = ({ dispatch }) => {
    const todoInput = useRef();
    useEffect(()=>todoInput.current.clear(),[todoText]);

      return (
          <TextInput 
              ref={todoInput}
              onSubmitEditing = { e => { dispatch(addTodo(e.nativeEvent.text)) } } 
          />
      )
    }
1
votes

Thanks @André Abboud by your help i was able to clear my TextInput field but according to my custom TextInput, i made a slight change in implementantion.

Please review the code and approach used for implementation. As far as i know now my requirement of clearing the TextInput as i needed is fullfilled and if required for any changes please notify in comment.

And what i did to make it work is:

In setupSender.js

  ...
  this.state = {
    clearInput: false,
    ...
  }

  ...           
  setupSenderSubmit = () => {
      ...
      this.setState({                             
        clearInput: !this.state.clearInput,
      })
      ...
  }
  ...
      <CustomTextInput
        labelText="First Name" 
        onChangeText={(firstName) => this.setState({ firstName })}
        clearInput={this.state.clearInput}
        value={this.state.firstName}
        returnKeyType={ 'next' }
        autoFocus={true}
        onSubmitEditing={() =>  this.input2.current.focus()}
      ></CustomTextInput>
  ...

And in CustomTextInput.js

  this.state={
    clearInput: this.props.clearInput, 
  }

  ...

  static getDerivedStateFromProps = (props, state) => { 
    if (props.clearInput !== '' || props.clearInput !== undefined) {
      return {
        clearInput: props.clearInput
      }
    }
    return null;
  }

  ...

    <TextInput 
      label={this.props.label} 
      value={!this.state.clearInput ? this.state.text : null}
      onChangeText={(text) => {
          this.setState({text});
          this.props.onChangeText(text)
        }
      }
    </TextInput>

  ...
1
votes

On my functional Component , I call another function along with submitHandler , that function will take care to clear text

const [text, setText] = useState('');
 const anotherFunc = (val) =>{
        setText('');
    }


    return (
        <View>
            <TextInput 
            value ={text}
            onChangeText ={changeHander}
            placeholder = 'Add '
           />
            <Button 
            title = "Add Something "
            onPress = {()=>  {submitHandler(text) , anotherFunc(text)}}
            />

        </View>
    )
1
votes

React-Native Using Input component from native-base. This worked for me:

<Input ref={input => {this.textInput = input;}}

and then:

this.textInput._root.clear();

Note: Did not have to use React.createRef() to initialise.

0
votes

I make this code for clearing TextInput in React Native OnSubmitEditing you can check my snack: https://snack.expo.io/@andreh111/clear-textinput-onsubmitediting

Here is the code:

state = {
    searchInput:'',
    clearInput:false
}
render(){
  return(



  <View style={{flex:1,justifyContent:'center',alignItems:'center'}}>
    <TextInput 
            style={{
              borderColor:'black',
              borderWidth:1,
              width:200,
              height:50
            }}
              onChangeText={(searchInput)=>this.setState({
                searchInput
              })}
              value={!this.state.clearInput ? this.state.searchInput : null}
              onSubmitEditing={()=>{
                this.setState({
                  clearInput:!this.state.clearInput,

                })

              }}
     />
</View>
)

}
0
votes
 <TextInput
        ref={input => { this.name = input }}
   />

         this.name.clear();
         this.email.clear();
         this.password.clear();
         this.confirmPassword.clear();
0
votes
      this.state = {
           commentMsg: '',
      }

after submittion 
     if (response.success)
     {
            this.commentMsg.clear();        //TODO me
     }


  <TextInput
     style={styles.textInput}
     multiline={true}
     ref={input => {
     this.commentMsg = input
       }}
     onChangeText={(text) => this.setState({commentMsg: text})}
     placeholder ='Comment'/>
0
votes

Work to me...

<TextInput
    ref={ref => {
                this.textInput = ref;
              }}
    ...
/>

after call function

clearMsg(){

    this.textInput.state.value = ''
}
0
votes

Also you can set the value of the <TextInput/> the same of the state and after use the data, set the state back to an empty string:

//state
const [state, setState] = useState({
  name: '',
  lastname: ''
})

//functions
const newUser = () => {
// Do your magic and after
  setState({
    name: '',
    lastname: ''
  })
}

const handleOnChange = () => {
  setState({
    // change your state
  })
}

//render
<TextInput
  value={state.name}
  placeholder='Name'
  onChangeText={/* execute your handleOnChange() */}
/>

<TextInput
  value={state.lastname}
  placeholder='Lastname'
  onChangeText={/* execute your handleOnChange() */}
/>

<Button title='Saved' onPress={() => newUser()} />

Hope to be usefull!

-1
votes

for RN > 0.6

const [msg, setMsg] = useState()

use value inside TextInput

<TextInput 
    onChangeText={(txt) => setMsg(txt)}}
    value={msg}
/>

then set state in your button press function like this

const pressButton = () => {
    setMsg('')
}