ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • React 웹페이지 복제과제 B
    web/react 2023. 1. 28. 09:17

    이전 과제내용을 블로그에 서술하던 중 코드가 이미 꽤 진행되어 있어 설명하기 어려운 부분이 많았다.

    글작성 후 사람인에 들어가보니 비슷한 과제가 또 있기에 실시간으로 블로그를 작성하며 해보려고 한다

    과제를 하기 앞서 사람인은 알람시스템을 수정하든 아니면 등록한 회사가 따로 연락을 넣든 하는게 좋을거같다 직접 뒤적거려 봐야 알수 있으니 아니면 아직 내가 배가 덜고픈 걸 수 도 있고

     

    또한 시작하기 앞서 이 글은 처음부터 시도해가면서 문제에 부딪치면 해결해 나가는 과정까지 모두 서술하므로 

    교육용으로는 적합하지 않고 과도하게 길어질거 같다

     

    과제는 이렇다

    첫번째

    이페이지와

    두번째

    이 두페이지를 만드는건데

    단 

    필수 사용 라이브러리

    공통

    • styled-components

    리액트 의 경우

    • grid
    • react-router-dom
    • react-icons

    리액트 네이티브의 경우

    • FlatList
    • react-navigation
    • @expo/vector-icons

    요부분이 있다는것.

     

    그럼 시작 언제나처럼 

    npx create-react-app 프로젝트이름

    을 먼저 해주자 

    그후 필수 사용라이브러리를 설치해준다

    npm install --save styled-components
    npm i react-grid-layout
    npm i react-router-dom
    npm install react-icons --save

    이렇게 까지

    여기에 더해서 모바일 화면을 구성해야 하니 

    npm install react-device-detect

    이것까지 해준다

    그리고 첫페이지 글을 적고 테스트 해보면...!

    import './App.css';
    import { MobileView } from 'react-device-detect'
    import { useState } from 'react'
    
    function App() {
      return (
        <div>
          <MobileView>
            
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
    
          </MobileView>
            
        </div>
      );
    }
    
    export default App;

    아무것도 안뜬다

    뭔데 왜안뜨는건데????

    황급히 와이파이 연결하고 모바일로 접속해보자

    되네..?

    그렇다 이놈 크롬개발자도구의 모바일버전까지 무시하고 진짜 물리적 모바일만 인식해 화면을 띄워주는 개쩔면서도 이상한놈이엇다

    미친라이브러리...라고 생각했는데 개발자도구 좀 만져주니까 보인다

    이 라이브러리를 쓸때 상단에 모바일로 꼭바꿔주자

    다음으로 할것은 

    아이디 인풋박스

    비밀번호 인풋박스

    로그인 버튼

    회원가입 버튼

    아이디 비밀번호 찾기 버튼이다

    function App() {
      return (
        <div>
          <MobileView>
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
            <Router>
              <main>
                <input ></input>
                <input ></input>
                <Link to="/logIn">
                  <button>Log In</button>
                </Link>
                <Link to="/singup">
                  <button>Sing Up</button>
                </Link>
                <Link to="/findPW">
                  <button>Find Kakao Account or Password</button>
                </Link>
              </main>
            </Router>
          </MobileView>
        </div>
      );
    }

    이렇게 요청한 react router dom 까지 사용해서 해주면

    엉성해보이지만 필요한건 다들어 있다

    css 나중에 만지고 다음 기능구현에 돌입하자

    로그인 버튼으로 다음 두번째 페이지에 들어가야 할텐데...

    들어가기 앞서 이젠 react router dom을 이렇게 하면 안된댄다

    또 바뀌엇네...

     

    이것저것 해보다가 결국 싹 밀고 처음부터 다시 했다.

     

    첫번째로 idex.js

    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    ReactDOM.render(
      <React.StrictMode>
          <App />
      </React.StrictMode>,
      document.getElementById('root')
    );
    
    reportWebVitals();

    이게 기존 코드 처음 프로젝트 생성하면 있는 코드에 reat-router-dom을 임포트 한 상태

    이상태로 진행하면

    Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot

     

    How to Upgrade to React 18 – React Blog

    As we shared in the release post, React 18 introduces features powered by our new concurrent renderer, with a gradual adoption strategy for existing applications. In this post, we will guide you through the steps for upgrading to React 18. Please report an

    reactjs.org

    이러한 오류가 발생한다 리액트 17버전에서나 쓰던거니까 바꾸란소린데...

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import './index.css';
    import App from './App';
    import reportWebVitals from './reportWebVitals';
    
    const rootNode = document.getElementById('root');
    
    ReactDOM.createRoot(rootNode).render(
      <React.StrictMode>
        <App />
      </React.StrictMode>,
    );
    
    reportWebVitals();

    이렇게 바꿔주고

    App.js 파일을 

    import Login from './component/Login';
    import Home from './component/Home';
    import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
    
    const App = () => {
      return (
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/Login" element={<Login />} />
          </Routes>
      );
    };
    
    export default App;

    좀더 깔끔하게 나눠 주면?

     

    Uncaught Error: useRoutes() may be used only in the context of a <Router> component.

    또 오류가 나는데 뭔소린고 하니

    Routes 를 또 다시 Router로 감싸주라는 소리같다.

    import Login from './component/Login';
    import Home from './component/Home';
    import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
    
    const App = () => {
      return (
        <Router>
          <Routes>
            <Route path="/" element={<Home />} />
            <Route path="/Login" element={<Login />} />
          </Routes>
        </Router>
      );
    };
    
    export default App;

    한번더 감싸지고 home.js 에 이전에 썻던 코드를 다시 연결해주자

    const Home = () => {
        return (
          <div>
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
            <input ></input>
                <input ></input>
                  <button>Log In</button>
                  <button>Sing Up</button>
                  <button>Find Kakao Account or Password</button>
          </div>
        );
      };
      
      export default Home;

    이렇게 다시 하면

    어찌저찌 다시 처음으로 돌아왔다..

    이제 여기서부터 또 다시 시작해야한다

    로그인 회원가입 아이디 패스워드 찾기 버튼을 누르면 해당 페이지로 이동해야하니

    react router dom을 이용해보자

    import { Link } from 'react-router-dom';
    
    const Home = () => {
        return (
          <div>
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
            <input ></input>
                <input ></input>
                  <Link to='/Login'>Log In</Link>
                  <Link to='/SingUp'>Sing Up</Link>
                  <Link to='/FindFW'>Find Kakao Account or Password</Link>
          </div>
        );
      };
      
      export default Home;

    Link를 import하고 button을 Link로 바꿔줫다 a태그랑 똑같은데 a테그를 사용하면 싱글페이지 랜더링이 아닌 다른페이지로 이동되게 되므로 link를 사용해야 한다

    Login.js 를 만들고

    const Login = () => {
        return (
          <div>
            <h1>로그인하면 보여주는 페이지</h1>
          </div>
        );
      };
      
      export default Login;

    Login을 눌러주면? 

    잘나온다

    localhost:3000/에서 뒤에 login이 붙엇다 잘된다

     

    근데 문득 그런생각이 든다 Link쓰는게 맞나?

    Router로 바꾸자

      return (
        <div>
        <Router>
           <Routes>
             <Route Link path="/*" element={<Home />} />
           </Routes>
         </Router>
         </div>
      );

    다음은 계정정보를 임시로 설정해준다

      const database = [
        {
          username: "kingking@gmail.com",
          password: "1212"
        },
        {
          username: "01012345678",
          password: "1234"
        },
        {
          username: "12",
          password: "12"
        }
      ];

    임시로 이메일과 비밀번호 핸드폰번호와 비밀번호 그리고 테스트할때 쉽게할수 있도록 아이디 12 비밀번호 12 로 세가지 샘플을 준비한다

     

    다음은 로그인 부분

      // 로그인 양식의 JSX 코드
      const LoginForm = (
        <div className="form">
          <form onSubmit={handleSubmit}>
            <div className="">
              <label>Username </label>
              <input type="text" name="uname"  />
              {renderErrorMessage("uname")}
            </div>
            <div className="">
              <label>Password </label>
              <input type="password" name="pass"  />
              {renderErrorMessage("pass")}
            </div>
            <div className="">
              <button type="submit" >Log In</button>
            </div>
            <div className="">
              <button >Sign Up</button>
            </div>
            <div className="">
              <button type="text" >Find Kakao Account or Password</button>
            </div>
          </form>
        </div>
      );

    입력받은 아이디와 정보를 handleSubmit 에 담고

     

    이후 입력한 사용자 아이디와 비밀본호를 비교할수 있는 코드

      const [errorMessages, setErrorMessages] = useState({});
      const [isSubmitted, setIsSubmitted] = useState(false);
    
        let { uname, pass } = document.forms[0];
        
    	const handleSubmit = (event) => {
        //페이지 다시 로드 방지
        event.preventDefault();
    
        let { uname, pass } = document.forms[0];
    
        // 사용자 로그인 정보 찾기
        const userData = database.find((user) => user.username === uname.value);
    
        // 사용자 정보 비교
        if (userData) {
          if (userData.password !== pass.value) {
            // 잘못된 암호
            setErrorMessages({ name: "pass", message: errors.pass });
          } else {
            setIsSubmitted(true);
          }
        } else {
          // 사용자 이름을 찾을 수 없음
          setErrorMessages({ name: "uname", message: errors.uname });
        }
      };

    userData를 비교해서 로그인 기능을 완성한다

     

    마지막으로 로그인이 안되있다면 로그인 폼을 보여주고 되어있다면 홈으로 보내주게 만들었다

     if(!isSubmitted){
        return(
          <div>
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
            {LoginForm}
          </div>
        )
      }
      return (
        <div>
        <Router>
           <Routes>
             <Route Link path="/*" element={<Home />} />
           </Routes>
         </Router>
         </div>
      );

    이렇게 까지 해놓으면

     

    아이디를 입력하면 다음화면으로 넘어가게된다

    import { useNavigate } from 'react-router-dom';
    
    
    const Home = () => {
    
        const navigate = useNavigate();
    
        return (
          <div>
            <p>1111111111</p>
            <button onClick={()=>{navigate("/Chat")}}>chat</button>
          </div>
        );
      };
      
      export default Home;

    홈코드는 임시로 간단하게 구현했다

    다음글에서 grid, react-icons 으로 css를 편집해보겠다

     

     

    코드전문

    import React, { useState } from "react";
    import { BrowserRouter as Router, Route, Routes } from 'react-router-dom';
    import "./App.css";
    import Home from "./component/Home";
    
    function App() {
      const [errorMessages, setErrorMessages] = useState({});
      const [isSubmitted, setIsSubmitted] = useState(false);
    
      const database = [
        {
          username: "kingking@gmail.com",
          password: "1212"
        },
        {
          username: "01012345678",
          password: "1234"
        },
        {
          username: "12",
          password: "12"
        }
      ];
    
      const errors = {
        uname: "invalid username",
        pass: "invalid password"
      };
    
      const handleSubmit = (event) => {
        //페이지 다시 로드 방지
        event.preventDefault();
    
        let { uname, pass } = document.forms[0];
    
        // 사용자 로그인 정보 찾기
        const userData = database.find((user) => user.username === uname.value);
    
        // 사용자 정보 비교
        if (userData) {
          if (userData.password !== pass.value) {
            // 잘못된 암호
            setErrorMessages({ name: "pass", message: errors.pass });
          } else {
            setIsSubmitted(true);
          }
        } else {
          // 사용자 이름을 찾을 수 없음
          setErrorMessages({ name: "uname", message: errors.uname });
        }
      };
    
      // 오류 메시지에 대한 JSX 코드 생성
      const renderErrorMessage = (name) =>
        name === errorMessages.name && (
          <div className="error">{errorMessages.message}</div>
        );
    
      // 로그인 양식의 JSX 코드
      const LoginForm = (
        <div className="form">
          <form onSubmit={handleSubmit}>
            <div className="">
              <label>Username </label>
              <input type="text" name="uname"  />
              {renderErrorMessage("uname")}
            </div>
            <div className="">
              <label>Password </label>
              <input type="password" name="pass"  />
              {renderErrorMessage("pass")}
            </div>
            <div className="">
              <button type="submit" >Log In</button>
            </div>
            <div className="">
              <button >Sign Up</button>
            </div>
            <div className="">
              <button type="text" >Find Kakao Account or Password</button>
            </div>
          </form>
        </div>
      );
      if(!isSubmitted){
        return(
          <div>
            <p>Welcome to KakaoTalk</p>
            <p>if you have a Kakao Account,</p>
            <p>log in with your email or phone number.</p>
            {LoginForm}
          </div>
        )
      }
      return (
        <div>
        <Router>
           <Routes>
             <Route Link path="/*" element={<Home />} />
           </Routes>
         </Router>
         </div>
      );
    }
    
    export default App;

    댓글

Designed by Tistory.