Hi I am doing some kind of form in react native and i have this checkbox component that works fine, but i cant get his value on my form.js. I have the same problem with other components like datepicker. im unable to pass the values
any suggestion would be aprreciated
this is my checkbox component
import { CheckBox } from 'react-native-elements';
export default class CheckBoxs extends Component {
constructor() {
super();
this.state = {
checked1: true,
checked2: false,
};
}
render() {
return (
<View style={styles.checkbox} >
<CheckBox
containerStyle={styles.checkbox}
textStyle={styles.checkboxTxt}
uncheckedColor={'#b3b4b5'}
checkedColor={"#911830"}
key={1}
title="Mujer"
value={1}
value="1"
checkedIcon="stop"
checked={this.state.checked1}
onPress={() => this.setState({ checked1: !this.state.checked1, checked2: this.state.checked1 })}
/>
<CheckBox
containerStyle={styles.checkbox}
textStyle={styles.checkboxTxt}
uncheckedColor={'#b3b4b5'}
checkedColor={"#911830"}
key={0}
title="Hombre"
value={0}
value="0"
checkedIcon="stop"
checked={this.state.checked2}
onPress={() => this.setState({ checked2: !this.state.checked2, checked1: this.state.checked2 })}
/>
</View>
);
}
}
this is my form code
import CheckBoxs from './CheckBoxs';
const PersonalForm = ({onSubmit, errorMessage}) => {
import CheckBoxs from './CheckBoxs';
const PersonalForm = ({onSubmit, errorMessage}) => {
const [vName, setvName] = useState('');
const [vSecondName, setvSecondName] = useState('');
const [vLastName, setvLastName] = useState('');
const [vSecondLastName, setvSecondLastName] = useState('');
const [vCellphone, setvCellphone] = useState('');
const [vBirthDate, setvBirthDate] = useState('');
const [vRFC, setvRFC] = useState('');
const [vGender, setvGender] = useState('');
const [vEmail, setvEmail] = useState('');
const [checked] = useState('false');
return (
<ScrollView>
<View style={styles.buttonContainer}>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="Apellido materno"
onChangeText={newvSecondLastName => setvSecondLastName(newvSecondLastName)}
underlineColorAndroid='transparent'
value={vSecondLastName}
autoCorrect={false}
autoCapitalize='characters'
/>
</View>
<View>
<MyDatePicker />
</View>
<View style={styles.checkbox} >
<CheckBoxs />
</View>
<View style={styles.inputContainer}>
<TextInput style={styles.inputs}
placeholder="Correo electrónico"
underlineColorAndroid='transparent'
onChangeText={newvEmail => setvEmail(newvEmail)}
value={vEmail}
autoCorrect={false}
autoCapitalize='characters'
/>
</View>
</View>
<View style={styles.buttonContainer2}>
<TouchableOpacity
style={ styles.logout}
onPress={() => onSubmit(vName, vSecondName, vLastName, vSecondLastName, vCellphone, vBirthDate, vRFC, vGender, vEmail),console.log(vName, vSecondName, vLastName, vSecondLastName, vCellphone, vBirthDate, vRFC, vGender, vEmail)}
>
<Text style={styles.loginText}>GUARDAR</Text>
</TouchableOpacity>
</View>
</ScrollView>
);
};
Have your component accept an 'onChange' callback (via props), and invoke it with the new value, whenever the value changes.
For example:
<Parent>
<Kid onChange={ newValue => { /* use the new value... */ } }/>
</Parent
Or another example:
const Parent = () => (
<View>
<TwoCheckboxes
onChange={
newValues => console.log('parent got new values', newValues)
}
/>
</View>
);
const TwoCheckboxes = props => {
const [ values, setValues ] = useState([ true, false]);
const [ val1, val2 ] = values;
const updateValuesAndReportChange = (newValues) => {
setValues(newValues);
props.onChange(newValues); /** this will pass updated values to Parent */
};
return (
<View>
<Checkbox
onPress={ () => updateValuesAndReportChange([ !val1, val2 ]) }
/>
<Checkbox
onPress={ () => updateValuesAndReportChange([ val1, !val2 ]) }
/>
</View>
);
};
In the React Native Docs:
This is a controlled component that requires an onValueChange callback that updates the value prop in order for the component to reflect user actions. If the value prop is not updated, the component will continue to render the supplied value prop instead of the expected result of any user actions.
So, add onValueChange to your Checkbox component. Store the value that it gives you in the component state, and pass that state to Checkbox through its value property.
An Example:
<Checkbox onValueChange={value => /** update **/} value={/** stored value **/} ... />
Related
I'm trying to put values from different TextInput's into 1 object. I'm new to React in general and don't have a firm grasp of states yet. So far my code is like this:
function App() {
const [enteredText, setEnteredText] = useState()
const [firstText, setFirstText] = useState()
const [secondText, setSecondText] = useState()
function textChange(enteredText) {
console.log(enteredText) //I want firstText and secondText here
}
return (
<View style={styles.container}>
<Text style={styles.header}>Great one!</Text>
<TextInput
value={firstText}
onChangeText={text=>setEnteredText(text)}
style={styles.input}
placeholder='1st text' />
<TextInput
value={secondText}
onChangeText={text=>setEnteredText(text)}
style={styles.input}
placeholder='2nd text' />
<Button
onPress={()=>textChange(enteredText)}
title='Submit'
color='orange' />
</View>
);
}
export default App;
You coud listen to firstText and secondText with useEffect and put them inside enteredText every time they change, like so:
function App() {
const [enteredText, setEnteredText] = useState();
const [firstText, setFirstText] = useState();
const [secondText, setSecondText] = useState();
function textChange(enteredText) {
console.log(enteredText); // will gives you {firstText : "whatever", secondText: "firstText"}
}
useEffect(() => {
setEnteredText({
firstText,
secondText,
});
}, [firstText, secondText]);
return (
<View style={styles.container}>
<Text style={styles.header}>Great one!</Text>
<TextInput
value={firstText}
onChangeText={(text) => setFirstText(text)}
style={styles.input}
placeholder="1st text"
/>
<TextInput
value={secondText}
onChangeText={(text) => setSecondText(text)}
style={styles.input}
placeholder="2nd text"
/>
<Button
onPress={() => textChange(enteredText)}
title="Submit"
color="orange"
/>
</View>
);
}
You're really close! What you want (enteredText) shouldn't actually be a state. It logically flows from the first and second texts, so you can just have it be a constant.
Like this:
function App() {
// changed the default state to be an empty string instead of
// the default undefined value. But either would work.
const [firstText, setFirstText] = useState("")
const [secondText, setSecondText] = useState("")
const enteredText = firstText + secondText
// I'd probably rename this function to "handleSubmit"
function textChange() {
console.log(enteredText)
}
return (
<View style={styles.container}>
<Text style={styles.header}>Great one!</Text>
<TextInput
value={firstText}
onChangeText={text=>setFirstText(text)}
style={styles.input}
placeholder='1st text' />
<TextInput
value={secondText}
onChangeText={text=>setSecondText(text)}
style={styles.input}
placeholder='2nd text' />
<Button
onPress={textChange}
title='Submit'
color='orange' />
</View>
);
}
export default App;
Note how I changed the onChangeText callbacks for the TextInputs
So you set firstText and secondText in their respective onClicks. Whenever the state is updated, the component rerenders, and runs all the code in the function body. the constant enteredText will be created on each run, and will always be the most recent concatenation of the two states.
Hope this helps!
I want to pass a value from my parent function to my child function.
but I don't know what to do.
please help advice
The language I use is react native. I want to send search data to main function
this is my code
Main Function
export default function Home() {
return (
<View>
<HeaderHome Upload={Upload} Uri={Uri} />
</View>
);
}
Second Function
export default function HeaderHome({ Upload, Uri }) {
const navigation = useNavigation();
const [showScrollView, setShowScrollView] = useState(false);
const [search, setSearch] = useState('');
const onPress = () => {
setShowScrollView(!showScrollView);
};
console.log(search);
return (
<View>
{showScrollView ? (
<View>
<TextInput
placeholder="Search..."
placeholderTextColor="#000"
onChangeText={(e) => setSearch(e)}
/>
<TouchableOpacity onPress={() => onPress()}>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
) : (
<View>
<View>
<Ionicons
name="md-search"
style={styles.iconSearch}
onPress={() => onPress()}
/>
<Ionicons
name="person-circle"
onPress={() => navigation.navigate('Menu', { Upload, Uri })}
/>
</View>
</View>
)}
</View>
);
}
Create a callback function that you pass as a prop from Home to HeaderHome. This could look as follows.
export default function Home() {
const [search, setSearch] = useState('')
return (
<View>
<HeaderHome setHomeSearch={setSearch} Upload={Upload} Uri={Uri} />
</View>
);
}
In HeaderHome you can call that function in the onPress function and set the state search in the Home component as follows.
export default function HeaderHome({ Upload, Uri, setHomeSearch }) {
const navigation = useNavigation();
const [showScrollView, setShowScrollView] = useState(false);
const [search, setSearch] = useState('');
const onPress = () => {
setShowScrollView(!showScrollView);
};
console.log(search);
const onSearchSet = (text) => {
setSearch(text)
setHomeSearch(text)
}
return (
<View>
{showScrollView ? (
<View>
<TextInput
placeholder="Search..."
placeholderTextColor="#000"
onChangeText={(e) => onSearchSet(e)}
/>
<TouchableOpacity onPress={() => onPress()}>
<Text>Cancel</Text>
</TouchableOpacity>
</View>
) : (
<View>
<View>
<Ionicons
name="md-search"
style={styles.iconSearch}
onPress={() => onPress()}
/>
<Ionicons
name="person-circle"
onPress={() => navigation.navigate('Menu', { Upload, Uri })}
/>
</View>
</View>
)}
</View>
);
}
Here I want to setName of parent component's state from child component while onCHangeText but it gives me "TypeError: setName is not a function. (In 'setName(text)', 'setName' is undefined)" error
Here is my Parent Component
const ProfileCreationScreen = () => {
const [name, setName] = useState()
const userSignup = async () => {
try {
firestore().collection('users').doc("androiduser_mobile89").set({
name: name,
});
alert("Succesfully Created")
} catch (error) {
alert(error);
}
};
return (
<SafeAreaView>
<Text>Create your account</Text>
<Button
mode="contained"
onPress={() => userSignup()}>
Sign Up
</Button>
<View style={{ display: "none" }}>
<NameScreen setName={setName} />
</View>
</SafeAreaView>
)
}
Here is my child component
export const NameScreen = ({ setName, navigation }) => {
return (
<KeyboardAvoidingView
enabled
behavior="padding"
style={styles.container}>
<View>
<Text style={styles.text}>Full Name</Text>
<TextInput
style={styles.textField}
label="Enter your Full Name"
underlineColor="#FF0074"
outlineColor="red"
value={text}
onChangeText={(text) => setName(text)}
/>
<Button mode="contained" style={styles.btn} onPress={() => alert(text)}>
Next
</Button>
</View>
</KeyboardAvoidingView>
);
In my Todo App i have sucessfully implemented the add and delete functions but the update function is having trouble. What i need it to do is when i click the touchable opacity of a Todo, it should appear in my inputbox and if any change is made then that todo should be updated e.g clicking on abcd must make it appear in input box and changes made to it should be updated. Picture is also added below
export default function Todo() {
const [getText, setText] = useState('');
const [getList, setList] = useState([]);
const addItem = () => {
setList([...getList, {key: Math.random().toString(), data: getText}]);
setText('');
}
const removeItem = (itemKey) => {
setList(() => getList.filter(item => item.key != itemKey));
}
const updateFieldChanged = (index) => e => {
let newArr = [...getList]; // copying the old datas array
newArr[index] = e.target.value; // replace e.target.value with whatever you want to change it to
setList(newArr);
}
return (
<View style={styles.container}>
<Text style={styles.title}>todo</Text>
<View style={styles.inputContainer}>
<TextInput
style={styles.textInput}
placeholder="Enter Item"
onChangeText={text => setText(text)}
value={getText}
/>
<CustomButton
text = 'add'
color='red'
title= 'add'
textSize={20}
textColor="white"
onPressEvent={addItem}
/>
</View>
<ScrollView style={styles.scrollview}>
{getList.map((item, id) =>
<TouchableOpacity
key={item.key}
activeOpacity={0.7}
onPress= {() => updateFieldChanged(id)}
>
<View style={styles.scrollviewItem}>
<Text style={styles.scrollviewText}>{id}) {item.data}</Text>
<TouchableOpacity
onPress={() => removeItem(item.key)}
>
<View style={styles.crosstextcontainer}>
<Text style={styles.crosstext}>X</Text>
</View>
</TouchableOpacity>
</View>
</TouchableOpacity>
)}
</ScrollView>
</View>
);
}
Change
<TouchableOpacity
key={item.key}
activeOpacity={0.7}
onPress= {() => updateFieldChanged(id)}
>
to
<TouchableOpacity
key={item.key}
activeOpacity={0.7}
onPress= {() => updateFieldChanged(id,getText)}
>
Here iam passing the text that you need to enter to update a particular field
change your updateFieldChanged like this:
const updateFieldChanged = (index, text) => {
let newArr = [...getList]; // copying the old datas array
newArr[index].data = text; // replace e.target.value with whatever you want to change it to
setList(newArr);
setText('');
}
Here iam assigning the text you entered in the TextInput to the data object, which will update the array.
Hope this helps!
this is my example that I try to check and unchecked the "check-boxes" but I get confused and i will be happy if someone shows me how it should be done.
import React, { useState } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { CheckBox } from 'react-native-elements';
const NewPlaceScreen = props => {
const [checked, setChecked] = useState(false);
return (
<View>
<CheckBox
iconRight
right
title="apple"
checked={checked}
onPress={() => setChecked(true)}
/>
<CheckBox
iconRight
right
title="kiwi"
checked={checked}
onPress={() => setChecked(true)}
/>
</View>
);
};
NewPlaceScreen.navigationOptions = {
headerTitle: 'viewsqq'
};
const styles = StyleSheet.create({
TextStyle: {
fontWeight: 'bold',
color: 'grey'
}
});
export default NewPlaceScreen
thats my example above
You need to set them to the opposite of their previous state when pressed. You can do this by using the setState callback:
onPress={() => setChecked(prev => !prev)}
At the moment your check boxes are both using the same state variable checked so they will stay in sync - changing one will change the other. If this is not what you want, you should create a separate state variable for each checkbox.
UPDATE:
To treat each checkbox independently, you need to create state for each checkbox:
const [isAppleChecked, setIsAppleChecked] = useState(false)
const [isKiwiChecked, setIsKiwiChecked] = useState(false)
return (
<View>
<CheckBox
iconRight
right
title="apple"
checked={isAppleChecked}
onPress={() => setIsAppleChecked(prev => !prev)}
/>
<CheckBox
iconRight
right
title="kiwi"
checked={isKiwiChecked}
onPress={() => setIsKiwiChecked(prev => !prev)}
/>
</View>
)
You need to have a separate state for each box, otherwise they will always show the same thing. And you need to set the new state to the opposite of the old state:
const NewPlaceScreen = props => {
const [appleChecked, setAppleChecked] = useState(false);
const [kiwiChecked, setKiwiChecked] = useState(false);
return (
<View>
<CheckBox
iconRight
right
title='apple'
checked={appleChecked} // use the apple-specific state
onPress={() => setAppleChecked(prevState => !prevState)} // use the new apple state function
/>
<CheckBox
iconRight
right
title='kiwi'
checked={kiwiChecked} // use the new kiwi state
onPress={() => setKiwiChecked(prevState => !prevState)} // use the new kiwi function
/>
</View>
);
};