react native how to focus on function component - react-native

I design a page to input account and password.
And I create a function component "LabelPwd" to password.
I want focus on password field after user submit account.
But nothing happened after submit account by the code below.
Can anyone provide some advise?
Main Page:
const [pwdFocused, setPwdFocused] = useState(false);
return (
<Controller
render={({ onChange, value }) => (
<LabelInput
error={errors ? errors.userId : errors}
label={t('common.userId')}
value={value}
autoFocus
onSubmitEditing={setPwdFocused(true)}
/>
)}
/>
<Controller
render={({ onChange, value }) => (
<LabelPwd
error={errors.password}
onChangeText={v => onChange(v)}
value={value}
setFocused={pwdFocused}
/>
)}
/>
);
LabelPwd
export default function LabelPwd({ value, onChangeText, error, setFocused }) {
const [pwdIcon, setPwdIcon] = useState('eye-off');
const pwdRef = useRef();
useEffect(() => {
//Seems didn't trigger here.
if (setFocused && pwdRef.current) {
pwdRef.current.focus();
}
}, [setFocused]);
function onPressPwdEye() {
if (pwdIcon === 'eye-off') {
setPwdIcon('eye');
setSecureMode(false);
} else {
setPwdIcon('eye-off');
setSecureMode(true);
}
}
return (
<>
<Input
errorMessage={error ? t('common.isRequired') : null}
label={t('common.password')}
rightIcon={{ type: 'feather', name: pwdIcon, size: 24, color: 'gray', onPress: onPressPwdEye }}
secureTextEntry={secureMode}
value={value}
onChangeText={onChangeText}
ref={pwdRef}
/>
</>
);
}

Related

React Native Validation with Formik - How can I replace the onchange of formik field with custom usestate hook?

I saw same question a couple of times but none of the answers made sense or solved it so maybe someone could help! I want to replace formiks onchange function with my own custom usestate hook. However, when I do that none of the validations work anymore, strangely none accept the error that field is required stays. Anyone know how to do it? Thanks!!
const DisplayingErrorMessagesSchema = Yup.object().shape({
password: Yup.string()
.min(2, 'Too Short!')
.max(50, 'Too Long!')
.required('Required'),
email: Yup
.string()
.email('Invalid email')
.required('Required')
.min(2, ({ min }) => `Password must be at least ${min} characters`)
});
const App = () => {
const { formData, handleInputChange } = useForm(
{
email: "",
password: ""
}
);
return (
<>
<Formik
initialValues={formData}
validationSchema={DisplayingErrorMessagesSchema}
onSubmit={values => console.log(values)}
>
{({ handleSubmit, isValid, values }) => (
<>
<Field
component={CustomInput}
name="title"
placeholder="Title"
/>
<Field
component={CustomInput}
name="post"
placeholder="Write post..."
multiline
numberOfLines={3}
/>
<Button
onPress={handleSubmit}
title="POST"
disabled={!isValid}
/>
</>
)}
</Formik>
</>
)
}
const CustomInput = (props) => {
const {
field: { name, onBlur, onChange, value },
form: { errors, touched, setFieldTouched },
...inputProps
} = props
const hasError = errors[name] && touched[name]
return (
<>
<TextInput
style={[
styles.textInput,
hasError && styles.errorInput
]}
value={value}
onChangeText={(text) => onChange(name)(text)}
onBlur={() => {
setFieldTouched(name)
onBlur(name)
}}
{...inputProps}
/>
{hasError && <Text style={styles.errorText}>{errors[name]}</Text>}
</>
)
}

How to clear input value after submit with LabelInput

I create a component as below.
It allows the user to input their id and submits it.
Now I want to clear the input value after submit.
How to implement?
const InputUserModal = ({ onConfirm }) => {
const { register, control, handleSubmit, errors } = useForm();
useEffect(() => {
register({ name: 'userId' }, { required: true });
}, [register]);
return (
<View>
<Controller
control={control}
name="userId"
defaultValue=""
render={({ onChange, value }) => (
<LabelInput
label='user'
iconSetting={{
name: 'user',
type: 'feather',
}}
onSubmitEditing={handleSubmit(onConfirm)}
autoFocus
onChangeText={v => onChange(v)}
value={value}
/>
)}
/>
</View>
);
};
As you're using Formik, It provides reset function, which you can pass as a reference in onConfirm as below:
const InputUserModal = ({ onConfirm }) => {
const { register, control, handleSubmit, errors,resetForm } = useForm();
useEffect(() => {
register({ name: 'userId' }, { required: true });
}, [register]);
return (
<View>
<Controller
control={control}
name="userId"
defaultValue=""
render={({ onChange, value }) => (
<LabelInput
label='user'
iconSetting={{
name: 'user',
type: 'feather',
}}
onSubmitEditing={handleSubmit(onConfirm(values,resetForm)}
autoFocus
onChangeText={v => onChange(v)}
value={value}
/>
)}
/>
</View>
);
};
Assume that you render this component as below
const ParentComponent = ()=>{
const handleOnConfirm =(values,resetForm)=>{
// Your function to submit input values to a server
// then resetFormik Values
resetForm()
}
return (
<InputUserModal onConfirm={handleOnConfirm}/>
)
}

How to use useEffect to change boolean values

I have 2 user text inputs called Search Location and Coordinates. I'm trying to use a checkbox when selected allows search location to be edited and the coordinates input be disabled and vice versa when the checkbox is not selected.
When i first run the code, i can edit Search Location and Coordinates is disabled. When i select the checkbox the text input works fine, Search Location is disabled and Coordinates is editable. However, when i try to unselect the checkbox, Search Location is still disabled and Coordinates can still be edited.
I have tried using useEffect but im not too familiar with this nor do i know if this is the correct approach. I am using react hook forms for user inputs and i use react native elements for checkboxes.
Code:
export default function UserInput({ navigation }) {
const { handleSubmit, control } = useForm();
const [checkbox, setCheck] = useState(false);
const [edit1, setEdit1] = useState(true);
const [edit2, setEdit2] = useState(false);
const onSelect = () => {
if (!checkbox) {
setEdit1(false);
setEdit2(true);
}
setCheck(!checkbox);
};
return (
<View style={styles.formContainer}>
<Text style={styles.text}>Distance(km)</Text>
<Controller
name="distance"
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, value } }) => (
<TextInput
placeholder="Enter your Distance"
style={styles.input}
onChangeText={onChange}
value={value}
/>
)}
/>
<Text style={styles.text}>Search Location</Text>
<Controller
name="searchLocation"
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, value } }) => (
<TextInput
placeholder="Enter your Coordinates"
style={styles.input}
onChangeText={onChange}
value={value}
editable={edit1}
/>
)}
/>
<CheckBox
center
title="Current Location"
checked={checkbox}
onPress={onSelect}
/>
<Text style={styles.text}>Coordinates</Text>
<Controller
name="coordinates"
control={control}
rules={{
required: true,
}}
render={({ field: { onChange, value } }) => (
<TextInput
placeholder="Enter your Coordinates"
style={styles.input}
onChangeText={onChange}
value={value}
editable={edit2}
/>
)}
/>
</View>
);
}
Try this one
const onSelect = () => {
if (!checkbox) {
setEdit1(false);
setEdit2(true);
} else {
setEdit1(true);
setEdit2(false);
}
setCheck(!checkbox);
};

React Native listIem passed props

I have a question about how to pass props for one screen to another, and display the props using listItem from "React Native Elements".
First i will paste the code of the screen with the "Add Friend" form:
const addFriend = ({ navigation }) => {
const [friend, setFriend] = useState('');
const [phone, setPhone] = useState('');
return (
<View style={styles.container}>
<Input
placeholder='Friend Name'
onChangeText={friend => setFriend(friend)}
leftIcon={
<Icon
name='user'
size={24}
color='grey'
/>
}
/>
<Input
onChangeText={phone => setPhone(phone)}
placeholder='Friend Phone Number'
leftIcon={
<Icon
name='phone'
size={24}
color='grey'
/>
}
/>
<Button
title="Add Friend"
onPress={() => {
navigation.navigate('FriendList', { friend, phone })
}}
/>
</View>
);
}
Second, i will paste the screen that is suppose to show the list of friends i want to add, here i cant find the way to pass the props from the screen above, to the list:
const list = [
{
name: '',
avatar_url: 'https://s3.amazonaws.com/uifaces/faces/twitter/ladylexy/128.jpg',
subtitle: ''
}
]
const FriendList = ({ route, navigation }) => {
const { friend } = route.params;
const { phone } = route.params;
return (
<View style={styles.container}>
list.map((l, i) => (
<ListItem
key={i}
leftAvatar={{ source: { uri: l.avatar_url } }}
title={l.name}
subtitle={l.subtitle}
bottomDivider
/>
))
}
{/* <Text>{JSON.stringify(friend)} {JSON.stringify(phone)}</Text> */}
</View>
);
}
You can find your parameters that you pass to your second screen in
let {friend, phone} = this.props.navigation.state.params;

How to Pass DatepickerIOS Date Object to Firebase (React Native)

I'm EXTREMELY new at coding, and I took Grinder's course on React Native. I have no idea how to save the datepickerios date object into Firebase. I'm pretty sure something in this code here is incorrect.
Any help would be greatly appreciated. Also, if anyone's looking for a mentee, I'd be grateful for your help. Thanks!
class ScoreForm extends Component {
constructor(props) {
super(props);
this.state = {chosenDate: new Date()};
this.setDate = this.setDate.bind(this);
}
setDate(newDate) {
this.setState({chosenDate: newDate});
}
render() {
return (
<View>
<CardSection>
<Text style={styles.pickerTextStyle}>Enter Date</Text>
</CardSection>
<CardSection>
{/* <Input
label="Date"
placeholder="MM/DD/YY"
value={this.props.date}
onChangeText={value => this.props.scoreUpdate({ prop: 'date', value })}
/> */}
<DatePickerIOS
style={{ flex: 1 }}
mode='date'
date={this.state.chosenDate}
onDateChange={value => this.props.scoreUpdate({ prop: 'date', value })}
/>
</CardSection>
<CardSection>
<Input
label="Score"
placeholder="Add Number"
value={this.props.score}
onChangeText={value => this.props.scoreUpdate({ prop: 'score', value })}
/>
</CardSection>
</View>
);
}
}
const styles = {
pickerTextStyle: {
fontSize: 18,
paddingLeft: 20
}
};
const mapStateToProps = (state) => {
const { date, score } = state.scoreForm;
return { date, score };
};
export default connect(null, { scoreUpdate }) (ScoreForm);
Since I am using Redux, I'm assuming I that I don't want to store it in state, correct? Here is the this.props.ScoreUpdate action:
export const scoreUpdate = ({ prop, value }) => {
return {
type: SCORE_UPDATE,
payload: { prop, value }
};
};