🤍 전 강의 25% 할인 중 🤍

2024년 상반기를 돌아보고 하반기에도 함께 성장해요!
인프런이 준비한 25% 할인 받으러 가기 >>

  • 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

AZURE 등록후 백엔드 프론트엔드 각각 잘올라왔는데 로그인을 하려고 보니 아래와 같은 에러가 발생해서 문의드립니다.

22.06.10 14:51 작성 조회수 146

0

- 여러분의 질문을 고대하고 있습니다. :-)
- 질문 전에 검색을 먼저 해보세요. 사람 사는 게 다 비슷하다는 것을 알게 됩니다.
- 예의는 거침없이 질문하기 위한 최고의 발명품입니다.
- 100개의 설명이 스크린샷 한방 보다 못할 수 있습니다.
- 코드를 첨부하면 전세계 누구나 이해할 수 있는 질문이 됩니다.
- 하나의 질문에는 하나의 주제를 담아야 답변도 예리해집니다.
- 시행착오를 알려주시면 곧 바로 원하는 문제에 집중할 수 있습니다.

- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
 

장고에서는 별다른 에러는 없는데 위 내용은 장고에서 username을 불러오지 못한다는 의미인걸까요..? 

답변 2

·

답변을 작성해보세요.

1

안녕하세요.

이는 JS 에서 undefined 으로부터 username 이름의 속성을 참조했기 때문에 TypeError가 발생했다는 오류입니다.

Login.js에서 실습을 하셨다면 Form 컴포넌트에 onFinish 속성값으로 onFinish 함수를 콜백으로 지정하셨을 텐데요. 이때 form submit이 이뤄질 때 onFinish 함수가 호출이 되고 인자로 form fields 값들이 넘어옵니다.

현재 Login.js 의 42번째 라인의 코드가 무엇인가요? 만약 const { username, password } = values; 라면, values이 각 필드값이 들어있는 object여야하는데 undefined라는 것은 현재 리액트 구현에 뭔가 문제가 있다는 것입니다.

혹시 속성값 지정 시에 onFinish={onFinish}  가 아니라 onFinish={onFinish()} 로 구현하신 것은 아닌가요?

코드를 차근차근 확인해보시며 정리해보시고나서, 다시 질문 부탁드립니다.

화이팅입니다. :-)

0

유형주님의 프로필

유형주

질문자

2022.06.12

안녕하세요 강사님 질문올린 후에 다시한번 코드를 수정해서 테스트 해봤는데 이번엔

 

어떤 오류도 발생하지 않고 새로고침만 실행 됬습니다. 

 

export default function Login() {
    const {dispatch} = useAppContext()
    const location = useLocation();
    const history = useHistory();
    const [errors, setErrors] = useState({});
    // const [inputs, setInputs] = useState({});
    const [username, setUsername] = useState('')
    const [password, setPassword] = useState('')
    const [loading, setLoading] = useState(false);
    const [formDisabled, setFormDisabled] = useState(false)
    const {from: loginRedirectUrl} = location.state || {
        from: {pathname : "/"}
    }

    const onSubmit = () => {
        // e.preventDefault()
        setErrors({});

        const data = {username, password}

        axiosInstance.post("/accounts/token/", data)
            .then(response => {
                const {
                    data : {
                        token: jwtToken,
                    }
                } = response
                dispatch(setToken(jwtToken))
                history.push(loginRedirectUrl)
            })
            .catch(error => {
                if (error.response) {
                    setErrors({
                        username: (error.response.data.username || []).join(""),
                        password: (error.response.data.password || []).join(""),
                    });
                    console.log('데이터 수신불가')
                    console.log(error.response)
                    history.go()
                }
            })
            .finally(() => {
                setLoading(true)
            });
    };

    useEffect(() => {
        const isEnable=  Object.values(username).every(s => s.length > 0);
        setFormDisabled(!isEnable)
    }, [username])

    const onUsernameChange = (e) => {
        setUsername(e.target.value)
    }

    const onPasswordChange = (e) => {
        setPassword(e.target.value)
    }

    return (
        <div className="app">
            {/* Start Header */}
            <div className="header">
                <div className="logo">
                    <LogoBox/>
                </div>
                <div className="search-bar">
                    <SearchBox/>
                </div>
                <div className="top-nav-bar">
                    <AccountMenu />
                </div>
            </div>
            {/* End Header */}


            <div className="signup">
                <Paper
                    sx={{
                        height: '600px',
                        width: '56%',
                        marginLeft: 28,
                        alignItems: 'center'
                    }}
                    elevation={9}
                >
                    <form onSubmit={onSubmit}>
                        <Stack alignItems={'center'} margin={10} spacing={3} >
                            <TextField
                                id="outlined-username-input"
                                label="Username"
                                type="username"
                                autoComplete="current-username"
                                name="username"
                                onChange={onUsernameChange}
                                sx={{ m: 1, width: '50ch' }}
                                InputProps={{
                                    startAdornment : (
                                        <InputAdornment position="start">
                                            <AccountCircle />
                                        </InputAdornment>
                                    )
                                }}
                            />
                            {errors.username}
                            <TextField
                                id="outlined-password-input"
                                label="Password"
                                type="password"
                                autoComplete="current-password"
                                name="password"
                                onChange={onPasswordChange}
                                sx={{ m: 1, width: '50ch' }}
                                InputProps={{
                                    startAdornment : (
                                        <InputAdornment position="start">
                                            <PasswordIcon />
                                        </InputAdornment>
                                    )
                                }}
                            />
                            {errors.password}
                            <Button
                                type="submit"
                                value="로그인"
                                disabled={loading || formDisabled}
                                variant="contained"
                                fullWidth
                            >
                                Login
                            </Button>
                            <Button
                                href="/accounts/signup/"
                                value="회원가입"
                                variant="contained"
                                fullWidth
                            >
                                Sign Up
                            </Button>
                        </Stack>
                    </form>
                </Paper>
            </div>

 

로컬해서 테스트할 떄는 정상적으로 작동하는데.... 혹시 프론트는 로컬과 클라우드로 올릴때 

코드가 다르게 적용되는 부분이 있나요? 위 코드는 Material UI 프레임워크를 사용해서 테스트하여

onFinish가 아닌 onSubmit으로 구현하였습니다. 

안녕하세요.

페이지가 새로고침이 된 것이 아니라, form 기본의 submit이 동작을 한 듯 하구요. <form>에 action지정이 없으니 현재 페이지로 submit이 동작을 하여 새로고침이 된 듯한 효과가 발생한 듯 합니다.

유형주 님께서는 <form> 의 기본 submit 동작을 수행하지 않고, 직접 구현하신 로직을 onSubmit을 통해 수행하실려는 것이잖아요. 그렇다면 form onSubmit에 지정된 onSubmit 함수에서 e.preventDefault()를 호출하거나 return false;를 해주셔야 합니다.

보여주신 코드에서는 e.preventDefault(); 를 호출하셨지만 주석처리를 하셨더라구요. e 객체는 onSubmit 함수의 첫번째 인자로 지정이 됩니다. 인자에서 e 객체를 받아서 호출해주시면 적어도 말씀하신 페이지가 새로고침이 되는 듯한 증상이 없어지지 않을까 싶습니다.

조급하게 생각하지 마시고, 차근차근 정리해보며 문제를 풀어가보세요. 이 모든 것이 하나 하나 쌓여 경험이 되는 것입니다.

화이팅입니다. :-)

채널톡 아이콘