How to implement TextInput without state [React-native] - reactjs

I'm working on an app which the users will enter large number of records continously. App functionalities are completed but the performance is bit slow in low end mobiles. As i'm new to react native i've not much idea on this. But when i googled reagrding this issue it has been noticed that when the state changes the whole app get rerenders. So for reducing the state changes i want to know how to use TextInput without using state . Because in my TextInput by using onChangeText the state is updating in every keypress.
This is a demo snack of the project Demo
<View style={styles.fixedform}>
<View style={styles.textinputViewleft}>
<TextInput
style={styles.textinput}
ref={firstref}
label="Digit"
returnKeyType="next"
value={digit.value}
onChangeText={(text) => { setDigit({ value: text, error: '' }); if (text.length === 3) { ref.current.focus(); } }}
error={!!digit.error}
errorText={digit.error}
keyboardType="numeric"
maxLength={3}
minLength={3}/>
</View>
<View style={styles.textinputView}>
<TextInput
style={styles.textinput}
ref={ref}
label="Count"
value={count.value}
onChangeText={(text) => setCount({ value: text, error: '' })}
error={!!count.error}
errorText={count.error}
keyboardType="numeric"
maxLength={3}/>
</View>
<View style={styles.textinputView}>
<Button loading={loading} disabled={disabled} style={styles.buttonView} mode="contained" onPress={onSubmitPress}>Submit</Button>
</View>
</View>

Try this way, It will not rerender on text change and hold the value on key press like
<TextInput
...
value={digit.value} // remove this
onChangeText={(text) => digit.value = text };
...
/>
To clear value, try one of this
1- firstref.current.clear();
2- firstref.current.setNativeProps({ text: '' });
3- firstref.current.value = '';

Related

Hide picked items in a FlatList

I'm using react-native FlatList to render out a punch on elements the data of which comes from an external API.
I want to prevent the user from picking the same item twice. So the way I'm going about this it hiding the item after they pick it.
If, let's say, I have a state picked like so
const [ picked, setPicked ] = useState(false);
changing it will of course hide all the elements.
<FlatList
{/*some other props*/}
data={allCards}
renderItem={(card: ListRenderItemInfo<CardsProps>) => (
<TouchableOpacity
style={[ styles.holder, { display: picked ? "none" : "flex" } ]}
onPress={() => handleChoice(parseInt(card.item.id))}
>
<Card
{/*some card props*/}
/>
</TouchableOpacity>
)}
/>
How can I go about changing the state for only one element inside the FlatList??
Is there a better approach you would recommend to do the same job?
try it like this, it will work,
<FlatList
{/*some other props*/}
data={allCards}
renderItem={(card: ListRenderItemInfo<CardsProps>) => picked ? (
<TouchableOpacity
style={[ styles.holder, ]}
onPress={() => handleChoice(parseInt(card.item.id))}
>
<Card
{/*some card props*/}
/>
</TouchableOpacity>
): undefined}
/>
The easiest way to do this is if you create an object with all the ids and while inserting it you can check it whether it's in that list or not
it'll cost u O(1) time to check.
<FlatList
{/*some other props*/}
data={allCards}
renderItem={(card: ListRenderItemInfo<CardsProps>) => picked ? (
<TouchableOpacity
style={[ styles.holder, ]}
onPress={() => handleChoice(parseInt(card.item.id))}
>
<Card
{/*some card props*/}
/>
</TouchableOpacity>
): undefined}
/>
const map=new Map();
const handleChoice=(id)=>{
if(Map.get(id)===undefined){
Map.set(id,true)
//add the element to ur list where u need it to
}
}

Problem Using KeyBoard avoiding view in Overlay

Can Any One Help Me with This Problem Actually I Am New To React Native I have tried a couple of ways to overcome this problem but nothing worked out please help me with this I don't want the keyboard to interfere with the overlay
<View style={{height:"9%"}}>
<Button title="Add A New ToDO" onPress={this.onPressOpenOverLay} buttonStyle={{height:"100%",borderBottomLeftRadius:30,borderBottomRightRadius:30}}/>
<Overlay isVisible={this.state.setVisible}
onBackdropPress={this.onPressCloseOverLay}
animationType="fade"
overlayStyle={{height:"70%",width:"90%",borderRadius:20,alignItems:"center",paddingTop:"15%"}}>
<Text style={{fontSize:19,color:"#0288D1",fontWeight:"bold"}}>Add A New ToDo</Text>
<TextInput style={styles.input}
placeholder="Email ID"
autoCapitalize="none"
underlineColorAndroid="transparent"
onChangeText={email => this.setState({ email })}
value={this.state.email}
>
</TextInput>
</Overlay>
</View>
<FlatList
style={{marginTop:"2%"}}
data={this.state.data}
renderItem={this._renderMyList}
keyExtractor={(item, index) => index.toString()}
bounces={true}
/>
</SafeAreaView>
)
}
}
If you set your width or height with percentage, then it is prone to change when some changes in UI layout like a keyboard appearing happens. so you need to give them pixel values.
Moreover, you could use the import {Dimension} from 'react-native' to give you the width and height of the device and then calculate the percentage of those values and give them to your view.

How to navigate to new page from TextInput field?

In this form i want to navigate to the new page as i click on the Field of Primary Address and Primary Bank Address
[In this form i want to navigate to new page conatining another form as i click on the field of primary address or primary bank account.]
<Text style={styles.labels}>
Address:
</Text>
<TextInput
style={styles.textinput}
placeholder="Primary Address"
placeholderTextColor="#000000"
mode="outlined"
underlineColorAndroid={'transparent'} />
<Text style={styles.labels}>
Bank Account:
</Text>
<TextInput
style={styles.textinput}
placeholder="Primary Bank Account"
placeholderTextColor="#000000"
mode="outlined"
underlineColorAndroid={'transparent'} />
Use ONFOCUS like
`onFocus={ () => this.onFocus() }
onFocus() {
},`
Wrap it inside a TouchableOpacity and take the user to next page using onPress
Also set editable prop to false in TextInput.

Unable to scroll over text input Android

Hey guys I'm facing a problem in scroll over TextInput in android.
In iOS everything working fine and when I use multiline={true}
it takes extra new line when go to next line.
How do I fix it? Here is my code:
<TextInput
placeholder='last name'
multiline={Platform.OS === 'ios'? false: true}
underlineColorAndroid='transparent'
scrollEnabled={Platform.OS === 'ios'? false: true}
blurOnSubmit = {Platform.OS === 'ios'? true: false}
numberOfLines={1}
style={[styles.formwelcome,]}
onChangeText={(text) => this.setState({lastname: text})}
autoGrow={ false }
ref='lastname'
returnKeyType='next'
onSubmitEditing={(event) => {this.refs.address.focus();}}/>
Add keyboardShouldPersistTaps="always" this property inside your ScrollView
So your ScrollView will look like
<ScrollView
keyboardShouldPersistTaps="always">
.....
</ScrollView>

Changing Visibility of a button inside the component dynamically

I am using React-Navigation but I guess You don't really need to have a prior knowledge about it.
So I have a header Component which looks like this
const Header = (props) => {
return (
<View style={headerContainer}>
<View>
<Button onPress={() => props.navigation.navigate('Home')}
title="Go Back"/>
</View>
<Text style={header}> Knicx
<Text style={headerSecondary}> Crypto Ticker </Text>
</Text>
</View>
)
}
Now, In the above notice the button, Which I am currently showing on all the pages
<Button onPress={() => props.navigation.navigate('Home')}
title="Go Back"/>
But I don't want it to be there on some specific pages, like HomeScreen to say the least.
Now, One solution is to remove the <Header /> component in my homepage, Copy the above code snippet, past it in my HomeScreen and remove the Component ( sort of like hardcoding ) or two create two Header component, one with button and one without button
[Question:] But I was thinking if we could toggle the visibility of button dynamically or stack it on the top of <Header /> ? Can someone please tell me how can we do it? (No, We can set the opacity of the button to zero and change it whenever we need it)
[Update:] We can use redux to manage/pass the state but the problem is that in React-native we do not have display: none and I don't want to change use the opacity
Send showHomeButton: boolean as a prop to header
const Header = props => (
<View style={headerContainer}>
{this.props.showHomeButton && (
<View>
<Button onPress={() => props.navigation.navigate('Home')} title="Go Back" />
</View>
)}
<Text style={header}>
{' '}
Knicx
<Text style={headerSecondary}> Crypto Ticker </Text>
</Text>
</View>
);

Resources