skip to Main Content

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 });
    },
    onError(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:

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.

2

Answers


  1. 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.

    Login or Signup to reply.
  2. 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>
    
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search