How to persist Redux Form Values? - react-native

I am using accordion-collapse-react-native to manage Sections. When i collapse that section and opens it again the redux form values disappear. How can i manage to maintain the state of the Redux Form Field Values. Thanks in advance.
Here is my code :
<Collapse style={styles.item} isCollapsed={this.state.isCollapsed_First}
onToggle={isCollapsed => this.setState({ isCollapsed_First: isCollapsed })}
>
<CollapseHeader style={styles.header}>
<View style={styles.headerContent}>
<Text style={styles.headerText} >Personal Information</Text>
<Icon name={this.state.isCollapsed_First ? "arrow-up" : "arrow-down"} size={18} color='#fff' />
</View>
</CollapseHeader>
<CollapseBody>
<View style={{flexDirection:'row',marginTop:7}}>
<View style={{width:'48%',marginRight:'4%'}}>
<Field name="first_name"
placeholder="First Name"
inputViewStyle={styles.inputView}
inputTextStyle={styles.inputText}
component={this.renderTextInput}
/>
</View>
<View style={{width:'48%'}}>
<Field name="last_name"
placeholder="Last Name"
inputViewStyle={styles.inputView}
inputTextStyle={styles.inputText}
component={this.renderTextInput}
/>
</View>
</View>
<View style={{flexDirection:'row',marginTop:-7}}>
<View style={{width:'100%'}}>
<Field name="dd_country"
placeholder="Country"
data = {this.state.countriesList}
onItemSelect={item => this.props.change('dd_country', item.id)}
textInputStyle={styles.inputView}
component={this.renderDropdownInput}
/>
</View>
</View>
<View style={{flexDirection:'row',marginTop:-7}}>
<View style={{width:'100%'}}>
<Field name="dd_ben_type"
placeholder="Beneficiary Type"
data = {this.state.custTypesList}
onItemSelect={item => this.props.change('dd_ben_type', item.id)}
textInputStyle={styles.inputView}
component={this.renderDropdownInput}
/>
</View>
</View>
</CollapseBody>
</Collapse>

You have to maintain it's state yourself.
Try maintaining the state in the component, something like this:
export function Form() {
const [name, setName] = useState('');
const [country, setCountry] = useState('');
return(
<View>
<Input
onChangeText={setName}
value={name}
placeholder='Name'
/>
<Input
onChangeText={setCountry}
value={country}
placeholder='Country'
/>
</View>
)
}

Related

Why keyboard disappears after entering one value (React Native Expo)?

I'm making a login form in React Native. I can login and register already but when I try to enter values in the TextInput fields in my register form, the keyboard disappears after I enter one value, so I have to re-click every time on the input field to re-open the keyboard. This does not happen on Android, just with iPhone.
The weird thing is that this behavior does not happen on the login screen even though it is built exactly the same. Does anyone have any idea why this is happening?
Register.js
return (
<View>
<TextInput
style={styles.input}
value={username}
onChangeText={(text) => setUsername(text)}
placeholder="username"
returnKeyType="next"
/>
<TextInput
style={styles.input}
value={fullname}
onChangeText={(text) => setFullname(text)}
placeholder="full name"
/>
<TextInput
style={styles.input}
value={password}
onChangeText={(text) => setPassword(text)}
placeholder="password"
/>
<PasswordStrengthMeterBar password={password} />
<Button title="Register" onPress={handleSubmit} />
</View>
);
Login.js
return (
<View style={styles.container}>
{this.state.showComponent ? (
<View>
<Text>
<Register setShowComponent={this.setShowComponent} />
</Text>
<Pressable onPress={this.handlePress}>
<Text>Login</Text>
</Pressable>
</View>
) : (
<View>
<TextInput
style={styles.input}
value={this.state.users_username}
onChangeText={this.handleusers_usernameChange}
placeholder="username"
/>
<TextInput
style={styles.input}
value={this.state.users_password}
onChangeText={this.handleusers_passwordChange}
placeholder="password"
secureTextEntry
/>
<Button title="Login" onPress={this.handleLoginPress} />
<Pressable onPress={this.handlePress}>
<Text>Register</Text>
</Pressable>
<Text>{this.state.response}</Text>
</View>
)}
</View>
);
I already updated my phone, but that has not solved anything.

KeyboardAvoidingView, ScrollView and Flatlist in a form

I have a form where I am using KeyboardAvoidingView and ScrollView so that when a user clicks on an input field the screen will scroll to that particular field
Within my form I have an input field that is searchable and I am using a FlatList to display the results for the user to choose from. Currently I am getting the error:
VirtualizedLists should never be nested inside plain ScrollViews
I've looked at many posts around this but am yet to find a solution (unless I've missed something):
1 - How to put FlatList inside of the ScrollView in React-native?
2 - FlatList inside ScrollView doesn't scroll
3 - How to make a FlatList scrollable inside of a ScrollView in react native?
This is what I have so far:
export const SignUpMember = ({navigation}) => {
const renderHeader = formikProps => {
return (
<>
<FormField
keyboardType={'default'}
fieldName={'firstName'}
label={'First Name'}
/>
<FormField
keyboardType={'default'}
fieldName={'lastName'}
label={'Last Name'}
/>
<FormField
onChangeText={text => {
formikProps.values.clubName = text;
searchItems(text);
}}
value={formikProps.values.clubName}
keyboardType={'default'}
fieldName={'clubName'}
label={'Club Name'}
placeholder={'Search Club By Name...'}
/>
</>
);
};
const renderFooter = formikProps => {
return (
<>
<FormField
keyboardType={'phone-pad'}
fieldName={'telephone'}
label={'Telephone'}
/>
<FormField
keyboardType={'email-address'}
fieldName={'email'}
label={'Email'}
/>
<FormField
keyboardType="default"
secureTextEntry={true}
fieldName={'password'}
label={'Password'}
type={'password'}
/>
<FormField
keyboardType="default"
secureTextEntry={true}
fieldName={'passwordConfirmation'}
label={'Confirm Password'}
type={'password'}
/>
<Button
mt="2"
bg="brand.blue"
type="submit"
onPress={formikProps.handleSubmit}>
Sign Up
</Button>
</>
);
};
return (
<KeyboardAvoidingView
keyboardVerticalOffset={headerHeight}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}>
<ScrollView
_contentContainerStyle={styles.container}
nestedScrollEnabled={true}>
<Box p="1" py="8" w="90%" maxW="290">
<VStack space={3} mt="5">
<Formik
initialValues={initialFormValues}
onSubmit={values => handleFormSubmit(values)}
validationSchema={userValidationSchema}>
{formikProps => (
<View>
<FlatList
nestedScrollEnabled={true}
data={flatListData}
renderItem={({item}) => (
<Pressable
onPress={() => {
formikProps.values.clubName = item.name;
setFlatListData([]);
}}>
<Text style={styles.flatList}>{item.name}</Text>
</Pressable>
)}
keyExtractor={item => item.name}
ListHeaderComponent={renderHeader(formikProps)}
ListFooterComponent={renderFooter(formikProps)}
/>
</View>
)}
</Formik>
</VStack>
</Box>
</ScrollView>
</KeyboardAvoidingView>
);
};
export default SignUpMember;
How can I piece this together?

container doesn't want to display full screen

my container doesn't want to display full width.. even though I have written the code as below, is there something wrong?
all my style code was here, I gave the background color to show there is a space at the end, and how to remove this until the color become fullscreen
this the code from name.txs
render() {
return (
<Container style = {styles.container}>
<VStack alignItems="center" alignContent="center">
<View style = {styles.view}>
<Text style={{fontSize:12, textAlign:'center'}}>
Please Input your Name
</Text>
<TextInput
style={styles.input}
placeholder='Enter Your Name Here'
onChangeText={ (name) => this.props.authStore.setName(name)}
/>
</View>
<View style = {styles.view}>
<Text style={{fontSize:12, textAlign:'center'}}>
Month of Your Born
</Text>
<TextInput
style={styles.input}
placeholder='January, February, etc.'
onChangeText={ (month) => this.props.authStore.setMonth(month)}
/>
</View>
<View style = {styles.view}>
<Text style={{fontSize:12, textAlign:'center'}}>
Day of Your Born
</Text>
<TextInput
keyboardType="numeric"
placeholder='1-31'
onChangeText={ (day) => this.props.authStore.setDay(day)}
/>
</View>
<View style = {styles.view}>
<Button
title="Submit"
onPress={() => this.props.navigation.push('Zodiac')}/>
</View>
</VStack>
</Container>
);
}
Replace <Container> with <Center flex={1}> from NativeBase

Formik handleChange - use hooks

before installing Formik, my input looked like so:
const [search, setSearch] = useState('');
....
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
name="search"
type="search"
value={search}
onChangeText={(e) => setSearch(e)}
autoCorrect={false}
defaultValue={search}
/>
<Button
disabled={!search}
title="Create"
onPress={(e) => {
createNewCar(e);
}}
/>
</View>
in onChangeText, I would set every character I typed to a state prop called search. With every key that I typed, an API called would be made to get some data from the db.
for example:
if I typed h into the input, the db would return 2 cars honda, hyundai
I read that Formik can simplify a lot of the form setup in React, so I downloaded it, however, the handleChange prop from Formik wants to keep track of values.search
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
handleChange(values.search);
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>
Now I can't type into the form because value is pointing at values.search instead of search like it did originally.
Question
How do I fire setSearch in onChangeText but also add search into the formik values prop?
you can make use of setFieldValue('search', e.target.value) instead of handleChange() change the code to the following:
<Formik
initialValues={{
search,
}}
onSubmit={(values) => {
console.log('values', values);
}}>
{({ handleChange, handleSubmit, values, setFieldValue }) => (
<View style={styles.profileEditContainer__top}>
<TextInput
style={styles.profileEditContainer__form}
autoCapitalize="none"
placeholder="Enter what you want to create.."
placeholderTextColor={Colors.formPlaceHolderDefault}
autoCorrect={false}
value={values.search}
onChangeText={(e) => {
//handleChange(values.search);
setFieldValue('search', e.target.value)
setSearch(e);
}}
/>
<Button
disabled={!search}
title="Create"
onPress={handleSubmit}
/>
</View>
)}
</Formik>

Rating not choosing more than 3 stars - React Native Elements - Rating)

I am using the Rating Element from the react-native-elements component. I noticed I can't choose more/less than 3 stars for my rating and I do not understand why.
Here is my code:
<Modal animationType={"slide"} transparent={false}
visible={this.state.showModal}
onDismiss={() => this.openModal()}
onRequestClose={() => this.openModal()}>
<View style={styles.modal}>
<Text style={styles.modalTitle}>Rating</Text>
<Rating
showRating
type="star"
imageSize={30}
onFinishRating={this.ratingCompleted}
style={{ paddingVertical: 10 }}
/>
<View style={styles.btnView}>
<Button
onPress={() => { this.handleFormSubmit() }}
color="#512DA8"
title="Submit"
style={styles.formBtn}
/>
<Button
onPress={() => { this.openModal();
this.resetForm(); }}
color="gray"
title="Cancel"
/>
</View>
</View>
</Modal>
What am I doing wrong?
I recommand to use AirbnbRating instead of Rating because it work for me.
Example code :
import {AirbnbRating } from 'react-native-elements';
<AirbnbRating
count={11}
reviews={["Terrible", "Bad", "Meh", "OK", "Good", "Hmm...", "Very Good", "Wow", "Amazing", "Unbelievable", "Jesus"]}
defaultRating={11}
size={20}
onFinishRating={rating => console.log(rating)}
/>
According to,
https://react-native-training.github.io/react-native-elements/docs/rating.html#ratingcount
you can use the prop ratingCount to set the number of rating images to display.
Try setting this to something other than 3.
Edit
Seems I misunderstood the query, please try setting readonly to false explicitly.
I would ask what do you have in function
onFinishRating={this.ratingCompleted}
I also used this component in my project and updated the state there:
<Rating
showRating
startingValue={4}
onFinishRating={rating => this.setState({ rating: rating })}
/>
Move the rating component in a function that returns the rating:
NOTE: this is a little bit strange, but it worked for me
Change your code like the following:
const RatingView=()=>{
return (
<Rating
showRating
type="star"
imageSize={30}
onFinishRating={this.ratingCompleted}
style={{ paddingVertical: 10 }}
/>
)
}
You Modal :
<Modal animationType={"slide"} transparent={false}
visible={this.state.showModal}
onDismiss={() => this.openModal()}
onRequestClose={() => this.openModal()}>
<View style={styles.modal}>
<Text style={styles.modalTitle}>Rating</Text>
<RatingView /> // Here ...
<View style={styles.btnView}>
<Button
onPress={() => { this.handleFormSubmit() }}
color="#512DA8"
title="Submit"
style={styles.formBtn}
/>
<Button
onPress={() => { this.openModal();
this.resetForm(); }}
color="gray"
title="Cancel"
/>
</View>
</View>
</Modal>