inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

파이썬/장고 웹서비스 개발 완벽 가이드 with 리액트

리액트 프로젝트를 Azure Storage에 배포하기

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

237

유형주

작성한 질문수 10

0

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

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

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

django react docker python

답변 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

유형주

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

 

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

 

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으로 구현하였습니다. 

0

이진석

안녕하세요.

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

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

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

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

화이팅입니다. :-)

안녕하세요.

0

62

1

[OneToOne Field Demo] get_user_model() 메서드를 활용해야 하는 이유?

0

282

1

useEffect 훅에서 else 유무에 따른 결과

0

221

1

useAxios 훅의 dependency array 설정

0

254

1

useEffect에서 변수 업데이트 관련 질문

0

388

1

rest_framework.generics.CreateAPIView의 model 속성 유무

0

273

1

bootstrap4

0

479

4

리뉴얼 강의가 오픈이 되면 기존 강의는 더이상 못보는걸까요

1

373

1

admin form에서 앞선 필드 선택 후 다른 필드 select widget 구성하는 방법

0

577

3

useState는 필수일까요?

0

269

1

python manage.py makemigrations instagram 시 created_at default 오류가 발생합니다.

0

606

4

Django allauth를 사용한 소셜 로그인 시 에러

0

657

1

프로젝트명 변경 뒤, 디버그툴바+디버그모드 사용 시 에러

0

561

2

useLocalStorage() 함수 사용여부

0

233

1

django에 LOGIN_URL = '/accounts/login/'의 의미?

0

451

1

리듀서의 의미 재확인

0

435

1

simple-jwt Refresh Token 사용 노하우

0

903

2

docker compose 를 통한 배포 관련 오류 문의

0

683

1

파이썬 속도 장고 관련 궁금한게 있습니다.

0

369

1

is_like_user

0

237

1

related_name 오류

0

276

1

re_path 오류

0

263

1

re_path url

0

252

1

No post matches the given query

0

667

2