관리 메뉴

bright jazz music

로그인 후 메인페이지 이동 (작업중) 본문

Framework/ReactJs

로그인 후 메인페이지 이동 (작업중)

bright jazz music 2023. 5. 22. 18:49

material-ui 라이브러리 설치

npm install @mui/material @emotion/react @emotion/styled
npm install @mui/material @mui/styled-engine-sc styled-components
npm install @fontsource/roboto
npm install @mui/icons-material

axios 설치

npm install axios

 

react-router-dom 설치

npm install react-router-dom

 

 

 

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import Main from "./Main";
import reportWebVitals from "./reportWebVitals";
import App from "./App";
import { BrowserRouter, HashRouter } from "react-router-dom";

const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
  <React.StrictMode>
    <HashRouter>
      <App />
    </HashRouter>
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

 

 

 

App.js

- const [loginState, setLoginState] = useState[false] 기본

- 서버에서 success 받으면 setLoginState(true)

- if ( loginState ===false) {<App />}

else if (loginState === ture) { <Main />

 

// import * as React from "react";
import { useState, useEffect } from "react";
import Avatar from "@mui/material/Avatar";
import Button from "@mui/material/Button";
import CssBaseline from "@mui/material/CssBaseline";
import TextField from "@mui/material/TextField";
import FormControlLabel from "@mui/material/FormControlLabel";
import Checkbox from "@mui/material/Checkbox";
import Link from "@mui/material/Link";
import Grid from "@mui/material/Grid";
import Box from "@mui/material/Box";
import LockOutlinedIcon from "@mui/icons-material/LockOutlined";
import Typography from "@mui/material/Typography";
import Container from "@mui/material/Container";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import axios from "axios";
import Main from "./Main";
import { Route, Routes, useNavigate } from "react-router-dom";

function Copyright(props) {
  return (
    <Typography
      variant="body2"
      color="text.secondary"
      align="center"
      {...props}
    >
      {"Copyright © "}
      <Link color="inherit" href="https://mui.com/">
        Your Website
      </Link>{" "}
      {new Date().getFullYear()}
      {"."}
    </Typography>
  );
}

// TODO remove, this demo shouldn't need to reset the theme.

const defaultTheme = createTheme();

//메인함수
function App() {
  const [login, setLogin] = useState("");
  const navigate = useNavigate();

  const handleSubmit = (event) => {
    // event.prevendDefault()를 하지 않으면 id, pw값이 get으로 전송되며, URL에 노출된다. 또한 브라우저가 새로고침된다.
    event.preventDefault();
    const data = new FormData(event.currentTarget); //FormData 객체를 사용하여 폼 데이터를 가져온다. event.currentTarget는 현재 이벤트가 발생한 요소인 <form> 요소를 가리킨다.
    console.log({
      email: data.get("email"),
      password: data.get("password"),
    });

    // const loginInfo = { email: data.email, passowrd: data.password }; //이 방법은 FormData 객체의 프로퍼티로 직접 접근하여 값을 가져오는 방식. 그러나 value가 undefined로 나와서 쓸 수 없다.
    const loginInfo = {
      email: data.get("email"), //get() 메서드를 사용하여 폼 필드의 값을 가져오는 방식으로, name속성(해당 태그의 name)을 인자로 전달하여 값을 가져온다.
      password: data.get("password"),
    };
    console.log("##loginInfo", loginInfo);

    axios
      .post("http://localhost:8080/axios/post", loginInfo)
      .then((response) => {
        console.log("###response.data", response.data);
        if (response.data.password.includes("10")) {
          console.log("##yes");
          localStorage.setItem("password-10", response.data.password);
          navigate("main");
        }
      })
      .catch((error) => {
        console.log(error);
      });
  };

  return (
    <ThemeProvider theme={defaultTheme}>
      <Container component="main" maxWidth="xs">
        <CssBaseline />
        <Box
          sx={{
            marginTop: 8,
            display: "flex",
            flexDirection: "column",
            alignItems: "center",
          }}
        >
          <Avatar sx={{ m: 1, bgcolor: "secondary.main" }}>
            {/** 아바타(아이콘과 유사) :   */}
            <LockOutlinedIcon />{" "}
            {/** 아무 설정 하지 않으면 사람모양의 기본 아바타가 표시된다.   */}
          </Avatar>
          <Typography component="h1" variant="h5">
            {/** <Typography> 컴포넌트를 사용하여 텍스트 스타일을 쉽게 적용할 수 있습니다 */}
            Sign in Test
          </Typography>
          <Box
            component="form"
            onSubmit={handleSubmit}
            noValidate //폼 유효성 검사를 비활성화 한다. 일반적으로 브라우저가 제공하는 기본 유효성 검사를 비활성화하고, 사용자 정의 유효성 검사 로직을 구현할 때 사용된다.
            sx={{ mt: 1 }}
          >
            <TextField //<TextField> 컴포넌트를 사용하면 텍스트 입력을 쉽게 처리할 수 있다
              margin="normal"
              required
              fullWidth
              id="email"
              label="Email Address"
              name="email"
              autoComplete="email" //입력 필드의 자동완성 기능을 설정.
              autoFocus //페이지가 로드될 때 입력필드에 자동으로 포커스를 설정한다.
            />
            <TextField
              margin="normal" //입력 필드의 마진을 normal로 설정
              required //필수 입력 설정
              fullWidth //입력 필드를 부모 컨테이너의 가로 폭에 맞게 확장. 즉 입력필드는 가로로 100%의 너비를 차지
              name="password" //입력 필드의 이름을 password로 설정. **서버 전송 시 해당 이름으로 식별된다.
              label="Password" //입력필드의 레이블을 "Password"로 설정. 필드 위에 텍스트로 표시됨
              type="password" // 입력 필드의 타입을 "password"로 설정. 입력값이 마스킹된다.
              id="password" //입력 필드의 고유한 식별자(id)를 "password"로 설정
              autoComplete="current-password" //입력 필드의 자동완성 기능을 설정함. "current-password"를 설정하면 브라우저는 사용자가 이전에 입력한 pw를 자동 제안가능.
            />
            <FormControlLabel //<FormControlLabel> 컴포넌트는 체크박스와 레이블을 함께 표시하는 역할을 한다.
              control={<Checkbox value="remember" color="primary" />} //Checkbox> 컴포넌트를 control prop으로 전달하여 체크박스를 생성. value는 값 설정.
              label="Remember me" //체크박스 옆에 표시되는 레이블 텍스트를 설정
            />
            <Button
              type="submit"
              fullWidth
              variant="contained" //contained: 버튼의 색이 차 있음. outlined: 안이 비어있고 테두리가 있음.
              sx={{ mt: 3, mb: 2 }} //버튼 스타일. 마진탑:위로 3 단위 만큼 간격 설정. 마진바텀:아래로 2만큼 간격 설정
            >
              Sign In
            </Button>

            <Grid container>
              {/* <Grid item xs={4}> 이렇게 하면 지정이고, 아래처럼 xs만 하면 자동으로 공간을 차지한다.  */}
              <Grid item xs>
                {/* 그리드 아이템을 생성하고, xs prop을 사용하여 해당 아이템이 자동으로 컨테이너의 남은 가로 공간을 차지하도록 설정 */}
                <Link href="https://google.com" variant="body2">
                  {"Forgot password?"}{" "}
                  {/** 중괄호로 감싸는 것은 JavaScript 표현식을 사용하기 위한 것으로,
                   * 텍스트 외에도 변수 또는 표현식을 포함할 수 있다.
                   * 하지만 이 예시에서는 단순히 정적인 텍스트인 "Forgot password?"를 사용하고 있으므로,
                   * 중괄호를 사용하지 않아도 동일한 결과를 얻을 수 있다 */}
                </Link>
              </Grid>

              <Grid item>
                <Link href="https://naver.com" variant="body2">
                  {"Don't have an account? Sign Up"}
                </Link>
              </Grid>
            </Grid>
          </Box>
        </Box>
        <Copyright sx={{ mt: 8, mb: 4 }} />
      </Container>

      <Routes>
        <Route path="/main" element={<Main />}></Route>
      </Routes>
    </ThemeProvider>
  );
}

export default App;

 

Main.js

import axios from "axios";
import { useState, useEffect } from "react";

function Main() {
  return (
    <div>
      <h1>main page!</h1>
    </div>
  );
}

export default Main;
Comments