Reputation:
I have a TextInput
and I don't want it to re render every time I change the value inside it
const [WrittenVal,setWrittenVal] = useState(()=>'');
...
<TextInput
value={String(WrittenVal)}
onChangeText={text => setWrittenVal(text)}
/>
but I want to be able to change the value inside the input at the push of a button that's why I haven't just used defaultValue
any solutions??
Upvotes: 4
Views: 9710
Reputation: 1
I also encountered a similar problem, but later I solved it using useMemo
hook.
Upvotes: 0
Reputation: 1
You can prevent re-render only using UseRef. const keyRef = useRef();
const keyToRef = (text)=>{
keyRef.text = text
}
<TextInput
ref={keyRef}
onChangeText={keyToRef}
value={keyRef?.text}
/>
Upvotes: 0
Reputation: 151
By doing this, you both prevent re-render and reset the text input value after clicking the button.
const ref = useRef("");
const inputRef = useRef(null);
const onChangeText = (item) => {
ref.current = item;
};
const addComment = async () => {
ref.current = "";
inputRef.current?.clear();
// Perform any other actions or logic you need here
};
return (
<View>
<TextInput ref={inputRef} onChangeText={onChangeText} />
<TouchableOpacity onPress={addComment}>
<Text>Send</Text>
</TouchableOpacity>
</View>
);
Upvotes: 0
Reputation: 415
const inputRef = useRef();
<TextInput
ref={inputRef}
onChangeText={text => inputRef.text = text }
/>
//function to get input value
const handleSubmit = () => {
let textInputValue = inputRef.text;
}
Upvotes: 7
Reputation: 180
If you have a nested component situation like the below you need to move the state into the component (under EpicComponent) the setWrittenVal will trigger a re-render on the EpicComponent. Common symptoms are the the field will lose focus when you type.
const Parent = ()=> {
const [WrittenVal,setWrittenVal] = useState(()=>'');
...
const EpicComponent = ()=> {
return (
<TextInput
value={String(WrittenVal)}
onChangeText={text => setWrittenVal(text)}
/> )
}
return (<EpicComponent/>)
}
Upvotes: 1
Reputation: 517
You can use useRef to save text from text input without render , and useState to show text in input on button press:
Live example : https://snack.expo.dev/TW-fMx1-2
import React from "react";
import { SafeAreaView, StyleSheet, TextInput,TouchableOpacity,Text } from "react-native";
const UselessTextInput = () => {
const [text, onChangeText] = React.useState("");
const textRef = React.useRef('')
const textToRef = (text) =>{
textRef.current = textRef.current + text
}
const showTextInInput = () =>{
onChangeText( textRef.current )
}
console.log("render")
return (
<SafeAreaView>
<TextInput
style={styles.input}
onChangeText={textToRef}
value={text}
/>
<TouchableOpacity onPress={showTextInInput}>
<Text>SHOW TEXT IN INPUT</Text>
</TouchableOpacity>
</SafeAreaView>
);
};
const styles = StyleSheet.create({
input: {
height: 40,
margin: 12,
borderWidth: 1,
marginTop:50,
padding: 10,
},
});
export default UselessTextInput;
Upvotes: 3
Reputation: 617
You can't prevent re-render on input when the value change.
But you can prevent other components to be re-renderd by React.memo
or useMemo
hook.
And for changing value of input with button press you can do like this:
<Button onPress={() => {
setWrittenVal(""); //write value you want in ""
}}
Upvotes: 0
Reputation: 1
You cannot prevent re-renders on type. But your code can be simplified to:
const [value, setValue] = useState('');
<TextInput
value={value}
onChangeText={setValue}
/>
Upvotes: 0