So im trying to make an authentication with react native and graphql apollo and im having some issues with it. This error pops up when i try typing on the name textinput.
SignIn.js
// ... other imports
import { useMutation } from '@apollo/client';
import { useForm } from '../constants/hooks';
const { onChange, onSubmit, values } = useForm(loginUserCallback, {
name: '',
password: '',
});
const [loginUser, { loading }] = useMutation(mutationData.LOGIN_USER, {
update(_, { data: { login: userData } }) {
// context.login(userData);
navigation.replace('Navigator'); // router.push("/");
// toast.success(`Logged In Successfully`, { autoClose: 800 });
},
one rror(err) {
console.log(err.graphQLErrors[0].extensions.errors);
},
variables: values,
});
function loginUserCallback() {
loginUser();
}
return (
<View>
<TextInput
value={values.name}
name="name"
onChangeText={onChange}
placeholder="Enter User Name"
/>
<TextInput
value={values.password}
name="password"
onChangeText={onChange}
placeholder="Enter Password"
/>
<TouchableOpacity onPress={onSubmit}>
<Text>SIGN IN</Text>
</TouchableOpacity>
</View>
);
hooks.js
import { useState } from 'react';
export const useForm = (callback, initialState = {}) => {
const [values, setValues] = useState(initialState);
const onChange = (event) => {
setValues({ ...values, [event.target.name]: event.target.value });
};
const onSubmit = (event) => {
event.preventDefault();
callback();
};
return {
onChange,
onSubmit,
values,
};
};
mutationData.js
import { gql } from '@apollo/client';
// =============
// Auth
// =============
const LOGIN_USER = gql`
mutation login($name: String!, $password: String!) {
login(name: $name, password: $password) {
id
email
username
createdAt
token
}
}
`;
const REGISTER_USER = gql`
mutation register(
$username: String!
$email: String!
$password: String!
$confirmPassword: String!
) {
register(
registerInput: {
username: $username
email: $email
password: $password
confirmPassword: $confirmPassword
}
) {
id
email
username
createdAt
token
}
}
`;
export default {
LOGIN_USER,
REGISTER_USER,
};
Extra Info:
- Im using expo for react native.
- All Imports have no issues.
- All Packages i have installed have no problems.
- CODESANDBOX LINK: https://codesandbox.io/s/modern-sound-boctx5?file=/src/SignIn.js
If i miss any details, which i know this is an uninformative post, pls tell in the comments and ill try my best to provide those information, also yes i tried working on the error for a few hours.
CodePudding user response:
Ok I think I've figured out your problem
One problem is that onChangeText
as @Appfred pointed out returns the value not the event
the second problem is that TextInput
doesn't have a name props so it ignore the one you are passing
you can resolve your problem with a few adjustments.
in your custom hook you need to change the onChange
signature like this
const onChange = (name, value) => {
setValues({ ...values, [name]: value });
};
and you need to modify your form in this way
<View>
<TextInput
value={values.name}
onChangeText={value => onChange('name', value)}
placeholder="Enter User Name"
/>
<TextInput
value={values.password}
onChangeText={value => onChange('password', value)}
placeholder="Enter Password"
/>
<TouchableOpacity onPress={onSubmit}>
<Text>SIGN IN</Text>
</TouchableOpacity>
</View>
or if you preferer a curried function approach you could do
const onChange = name => value => {
setValues({ ...values, [name]: value });
};
and then
<View>
<TextInput
value={values.name}
onChangeText={ onChange('name') }
placeholder="Enter User Name"
/>
<TextInput
value={values.password}
onChangeText={ onChange('password') }
placeholder="Enter Password"
/>
<TouchableOpacity onPress={onSubmit}>
<Text>SIGN IN</Text>
</TouchableOpacity>
</View>
CodePudding user response:
According to React Native's documentation on the onChangeText function for TextInput:
Changed text is passed as a single string argument to the callback handler.
Thus, event
is the string, event.target
is undefined, and when trying get event.target.name
you get this error. To grab the target and name, use the onChange function instead, with event
swapped out for nativeEvent
.