Next js 13 注册表单提交事件处理程序有两个 POST 请求,并在第二个 POST 请求上给出 500 状态代码

问题描述 投票:0回答:1

我是 Next js 的新手。我想向我的 json 服务器的 /currentUser 端点以及 /users 提交一个发布请求。但是,当我提交表单时,第一个发布请求很好,但第二个发布请求时出现错误。难道有什么原因不允许两次发帖请求吗?

控制台中似乎没有提供太多线索。我尝试过检查拼写错误,但一切看起来都不错。我尝试使用提交事件侦听器断点以及 localhost:4000/users 的获取断点来筛选调用堆栈。我希望在能够注册用户后它会将我发送到主页“/”,但它却将我发送到未找到的页面并在控制台中为我提供 500 状态代码。

这是我的 RegisterForm.jsx 代码:

"use client"

import { v4 as uuid } from 'uuid';

import { useRouter } from 'next/navigation';
import { useState, useEffect } from 'react';

async function checkLoginStatus() {

    // This function requests the currentUser from db.json.
    // Whenever someone logs in or registers, currentUser gets filled.
    // If currentUser is empty, then isLoggedIn should be false and
    // user should be redirected to /account or be 
    // allowed to go to /account/register or /account/login
    // to fill out that information.

    const res = await fetch('http://localhost:4000/currentUser', {
        next: {
            revalidate: 0
        }
    });
    const currentUser = await res.json();
    
    const { name } = currentUser;
    
    let isLoggedIn = false;
    
    if (name !== '') {
        isLoggedIn = true;
    } else if (name === '') {
        isLoggedIn = false;
    }
    
    return isLoggedIn;
}

export default function RegisterForm() {
    const router = useRouter();

    const [isInputDisabled, setIsInputDisabled] = useState(false);
    const [name, setName] = useState('');
    const [username, setUsername] = useState('');
    const [email, setEmail] = useState('');
    const [password, setPassword] = useState('');
    const [confirmPassword, setConfirmPassword] = useState('');

    const handleChange = (event) => {
        if (event.target.id === "register-name-input") {
            setName(event.target.value);
        } else if (event.target.id === "register-username-input") {
            setUsername(event.target.value);
        } else if (event.target.id === "register-email-input") {
            setEmail(event.target.value);
        } else if (event.target.id === "register-password-input") {
            setPassword(event.target.value);
        } else if (event.target.id === "register-confirm-password-input") {
            setConfirmPassword(event.target.value);
        }
    }
    
    function handleReset() {
        setName('');
        setUsername('');
        setEmail('');
        setPassword('');
        setConfirmPassword('');
    }

    let isPasswordConfirmed = true;
    let isAccount = false;

    const handleSubmit = async (event) => {

        event.preventDefault();

        // before we check for an existing user,
        // we need to check if the confirmed password matches the password.

        if (confirmPassword === password) {
            isPasswordConfirmed = true;
        } else {
            isPasswordConfirmed = false;
        }

        if (isPasswordConfirmed) {

            // after confirming that both password input values are the same,
            // if the user info is unrecognized in '/users', 
            // currentUser will be updated in '/currentUser',
            // which indicates which user's data needs to be displayed,
            // and a new user will be created in '/users'
            
            const fetchedUsersResponse = await fetch('http://localhost:4000/users', {
                next: {
                    revalidate: 0
                }
            });

            const fetchedUsers = await fetchedUsersResponse.json();

            for (let userIndex = 0; userIndex < fetchedUsers.length; userIndex++) {

                if (username === fetchedUsers[userIndex].user.username
                    || email === fetchedUsers[userIndex].user.email
                ) {  
                    isAccount = true;
                } else {
                    isAccount = false;
                }
            }

            if (!isAccount) {

                const currentUser = {
                    name, 
                    username, 
                    email, 
                    password
                }
      
                const currentUserRes = await fetch('http://localhost:4000/currentUser', {
                    method: 'POST',
                    headers: {"Content-Type": "application/json"},
                    body: JSON.stringify(currentUser)
                })

                if (currentUserRes.status === 201) {
                    // do nothing
                } else {
                    router.push('/not-found');
                }

                const newUser = {
                    user_id: uuid(),
                    user: {
                      name: currentUser.name,
                      username: currentUser.username,
                      email: currentUser.email,
                      password: currentUser.password
                    },
                    data: {
                      folders: [],
                      media: []
                    }
                }

                const newUserRes = await fetch('http://localhost:4000/users', {
                    method: 'POST',
                    headers: {"Content-Type": "application/json"},
                    body: JSON.stringify(newUser)
                })

                if (newUserRes.status === 201) {
                    router.push('/');
                } else {
                    router.push('/not-found');
                }
            }
        }
    }

    useEffect(() => {
        // useEffect allows us to do async functions.
        // On the initial render, we need to check 
        // to see if the user has logged in. If so, then the
        // user should get redirected to "/".
        // If not, the user should only be allowed to
        // navigate around /account

        const checkLogin = async () => {
        const isLoggedIn = await checkLoginStatus()
            if (isLoggedIn === false) {
                // do nothing
            } else {
                setIsInputDisabled(true);
                router.push('/')
            }
        }
        checkLogin()
    }, [])

    

    return (
        <form onSubmit={handleSubmit}>
            <div>
                <div>
                    <label htmlFor="register-name-input">Name</label>
                    <input required type="text" id="register-name-input" value={name} onChange={handleChange} disabled={isInputDisabled} />
                </div>

                <div>
                    <label htmlFor="register-username-input">Username</label>
                    <input required type="text" id="register-username-input" value={username} onChange={handleChange} disabled={isInputDisabled} />
                </div>

                <div>
                    <label htmlFor="register-email-input">Email</label>
                    <input required type="email" id="register-email-input" value={email} onChange={handleChange} disabled={isInputDisabled} />
                </div>

                <div>
                    <label htmlFor="register-password-input">Password</label>
                    <input required type="password" id="register-password-input" value={password} onChange={handleChange} disabled={isInputDisabled} />
                </div>

                <div>
                    <label htmlFor="register-confirm-password-input">Confirm Password</label>
                    <input required type="password" id="register-confirm-password-input" value={confirmPassword} onChange={handleChange} disabled={isInputDisabled} />
                </div>

                {!isPasswordConfirmed && <p>Please ensure that your password is typed correctly.</p>}
            </div>

            <div>
                <button type="submit">OK</button>
                <button type="button" onClick={handleReset}>Reset Fields</button>
            </div>

            {isAccount && <p>Username/Email already in use, navigate to Login instead.</p>}
        </form>
    )
}

如果您有任何建议,请告诉我

谢谢你

post fetch-api next.js13 http-status-code-500 json-server
1个回答
0
投票

我查看了这个 Github 讨论,它提到有一个简单地命名为“id”的属性。我尝试在 POST 请求中提交的 id 属性称为“user_id”。我的错!

© www.soinside.com 2019 - 2024. All rights reserved.