简体   繁体   中英

How to handle Uncaught Error: Objects are not valid as a React child error

What is the best way to handle the user input errors returned from GraphQL resolver? I am trying to code user singup using react and graphql. I would like to user errors like email is taken or some other validation message on the form.

Currently I am getting the following on browser window

Unhandled Runtime Error Error: Objects are not valid as a React child (found: Error: Error: Email already taken). If you meant to render a collection of children, use an array instead.

React Component

import React, { useState } from "react";
import { gql, useMutation } from "@apollo/client";
import Form from "./styles/form";
import Router from "next/router";

const SIGNUP_MUTATION = gql`
    mutation SIGNUP_MUTATION(
        $email: String!
        $password: String!
        $name: String!
    ) {
        signup(email: $email, password: $password, name: $name) {
            email
            username
            password
            profile
            token
        }
    }
`;

const SignupComponent = () => {
    const [values, setValues] = useState({
        email: "",
        name: "",
        password: "",
        error: "",
        loading: false,
        message: "",
        showForm: true,
    });

    const { name, email, password, message, showForm } = values;

    const handleChange = (name) => (e) => {
        setValues({ ...values, error: false, [name]: e.target.value });
    };
    const showLoading = () =>
        loading ? <div className="alert alert-info">Loading...</div> : "";
    const showError = () =>
        error ? <div className="alert alert-danger">{error}</div> : "";
    const showMessage = () =>
        message ? <div className="alert alert-info">{message}</div> : "";

    const [signup, { loading, error }] = useMutation(SIGNUP_MUTATION, {
        variables: {
            email: email,
            password: password,
            name: name,
        },
    });

    const handleSubmit = async (e) => {
        e.preventDefault();

        try {
            await signup();
            if (error) {
                setValues({ ...values, loading: true, error: true });
            }
        } catch (err) {
            console.log(err);
        }

        if (error) {
            setValues({
                ...values,
                loading: false,
                error: error,
                showForm: true,
                message: "",
            });
        } else {
            setValues({
                ...values,
                loading: false,
                error: "",
                showForm: false,
                message: " Signup successful. Please signin",
            });
        }
    };

    const signupForm = () => {
        return (
            <div>
                <Form method="post" onSubmit={handleSubmit}>
                    <fieldset>
                        <h2>Sign Up for An Account</h2>
                        <div className="form-group">
                            <input
                                value={name}
                                onChange={handleChange("name")}
                                type="text"
                                className="form-control"
                                placeholder="Type your name"
                            />
                        </div>
                        <div className="form-group">
                            <input
                                value={email}
                                onChange={handleChange("email")}
                                type="email"
                                className="form-control"
                                placeholder="Type your email"
                            />
                        </div>
                        <div className="form-group">
                            <input
                                value={password}
                                onChange={handleChange("password")}
                                type="password"
                                className="form-control"
                                placeholder="Type your password"
                            />
                        </div>
                        <div>
                            <button className="btn btn-primary">Signup</button>
                        </div>
                    </fieldset>
                </Form>
            </div>
        );
    };

    return (
        <>
            {showError()}
            {showLoading()}
            {showMessage()}
            {showForm && signupForm()}
        </>
    );
};

export default SignupComponent;

Resolver

    Mutation: {
        signup: async (__, { email, password, name }) => {
            try {
                const user = await userService.signup({
                    name,
                    email,
                    password,
                });
                const token = await jwt.sign({ _id: user._id }, APP_SECRET);
                const { profile, userName } = user;

                const authtype = {
                    token,
                    username: userName,
                    password,
                    name,
                    email,
                    profile,
                };
                return authtype;
            } catch (error) {
                // throw new Error(error)
                throw  error;
            }
        },

You shouldn't use object in {} . error is object type, not a string so should transform it into a string type for render.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM