[TIL/React] 2023/07/01

원민관·2023년 7월 1일
0

[TIL]

목록 보기
89/159

파일 구조

App.js

import React from "react";
import HomePage from "./pages/HomePage";

function App() {
  return (
    <>
      <HomePage />
    </>
  );
}

export default App;

최상단인 App.js에서는 Homepage 컴포넌트만을 보여줌

src/pages/Homepage.js

import React, { useRef } from "react";
import AppBar from "../components/appbar/AppBar";
import Footer from "../components/footer/Footer";
import Common from "../components/common/Common";
import HomeComponent from "../components/HomeComponent";
import AddTaskComponent from "../components/AddTaskComponent";
import RecentTodoComponent from "../components/RecentTodoComponent";
import MyTodoComponent from "../components/MyTodoComponent";

const HomePage = () => {
  const homeRef = useRef(null);
  const addRef = useRef(null);
  const recentRef = useRef(null);
  const myRef = useRef(null);

  const handleScroll = (ref) => {
    ref.current.scrollIntoView({ behavior: "smooth" });
  };

  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <AppBar
        handleHomeClick={() => handleScroll(homeRef)}
        handleAddClick={() => handleScroll(addRef)}
        handleRecentClick={() => handleScroll(recentRef)}
        handleMyClick={() => handleScroll(myRef)}
      />

      <Common>
        <HomeComponent ref={homeRef} />
        <AddTaskComponent ref={addRef} />
        <RecentTodoComponent ref={recentRef} />
        <MyTodoComponent ref={myRef} />
      </Common>

      <Footer />
    </div>
  );
};

export default HomePage;

homepage는 크게 1)AppBar, 2)Common, 3)Footer 로 구성

src/components/appbar/AppBar.js

import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { styled } from "styled-components";
import { getTodo } from "../../features/todosSlice";
import { HiChevronDoubleRight } from "react-icons/hi";
import { logo } from "../../images";

const Header = styled.div`
  background-color: #c07848;
  width: 100%;
  height: 10vh;
  position: sticky;
  top: 0;
  z-index: 999;
`;

const HeaderWrapper = styled.div`
  max-width: 1200px;
  display: flex;
  margin: 0 auto;
  height: 100%;
  /* background-color: red; */
  padding: 0px 12px;
  @media (max-width: 900px) {
    display: none;
  }
`;

const LogoContainer = styled.div`
  width: auto;
  height: 100px;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-right: 40px;
`;
const Logo = styled.img`
  width: auto;
  height: 80px;
`;

const NavButtonContainer = styled.div`
  display: flex;
  align-items: center;
  column-gap: 40px;
`;

const NavButton = styled.button``;

const HamburgerIconContainer = styled.div`
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-grow: 1;
`;

const AppBar = ({
  handleHomeClick,
  handleAddClick,
  handleRecentClick,
  handleMyClick,
}) => {
  const { loading } = useSelector((state) => state.todos);
  const dispatch = useDispatch();

  useEffect(() => {
    dispatch(getTodo());
  }, []);

  if (loading) {
    return <p>로딩중</p>;
  }

  return (
    <div>
      <Header>
        <HeaderWrapper>
          <LogoContainer>
            <Logo src={logo} />
          </LogoContainer>
          <NavButtonContainer>
            <button onClick={handleHomeClick}>Home</button>
            <button onClick={handleAddClick}>AddTask</button>
            <button onClick={handleRecentClick}>RecentTodo</button>
            <button onClick={handleMyClick}>MyTodo</button>
          </NavButtonContainer>
          <HamburgerIconContainer>
            <HiChevronDoubleRight />
          </HamburgerIconContainer>
        </HeaderWrapper>
      </Header>
    </div>
  );
};

export default AppBar;

AppBar 컴포넌트는 크게 1)Logo, 2)NavButton, 3)Hamburger icon 으로 구성

미디어 쿼리를 사용하여 화면이 900px 이하로 줄어들면 AppBar에 관한 내용이 나오지 않도록 시도해봄

src/components/common/Common.js

import React from "react";
import { styled } from "styled-components";

const Content = styled.div`
  height: 100vh;
  display: flex;
  flex-direction: column;
`;

const Common = ({ children }) => {
  return <Content style={{ flexGrow: 1 }}>{children}</Content>;
};

export default Common;

Common으로 감싸진 컴포넌트들

HomeComponent

import React from "react";
import { styled } from "styled-components";
import { forwardRef } from "react";

const HomeComponentWrapper = styled.div`
  background-color: black;
  min-height: 100%;
`;

const HomeComponent = forwardRef((props, ref) => {
  return <HomeComponentWrapper ref={ref}>gd</HomeComponentWrapper>;
});

export default HomeComponent;

AddTaskComponent

import React from "react";
import { styled } from "styled-components";
import { forwardRef } from "react";

const AddTaskComponentWrapper = styled.div`
  background-color: gray;
  min-height: 100%;
`;

const AddTaskComponent = forwardRef((props, ref) => {
  return <AddTaskComponentWrapper ref={ref}>gd</AddTaskComponentWrapper>;
});

export default AddTaskComponent;

RecentTodoComponent

import React from "react";
import { styled } from "styled-components";
import { forwardRef } from "react";
const RecentTodoComponentWrapper = styled.div`
  background-color: black;
  min-height: 100%;
`;

const RecentTodoComponent = forwardRef((props, ref) => {
  return <RecentTodoComponentWrapper ref={ref}>gd</RecentTodoComponentWrapper>;
});

export default RecentTodoComponent;

MyTodoComponent

import React, { forwardRef } from "react";
import { styled } from "styled-components";

const MyTodoComponentWrapper = styled.div`
  background-color: gray;
  min-height: 100%;
`;

const MyTodoComponent = forwardRef((props, ref) => {
  return (
    <MyTodoComponentWrapper ref={ref}>내 할 일 컴포넌트</MyTodoComponentWrapper>
  );
});

export default MyTodoComponent;

src/components/footer/Footer.js

import React from "react";
import { styled } from "styled-components";

const FooterWrapper = styled.div`
  background-color: #fff;
  display: flex;
  height: 20vh;
  width: 100%;
  justify-content: space-around;
  margin: 0 auto;
`;

const FooterTextContainer = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
`;

const NavButtonContainer = styled.div`
  display: flex;
  align-items: center;
  column-gap: 40px;
`;

const Footer = () => {
  return (
    <div>
      <FooterWrapper>
        <FooterTextContainer>
          <p>My task</p>
          <p>Copyright © 2023 All rights reserved</p>
          <p>Powered By SITE123 - Create your own website</p>
        </FooterTextContainer>
        <NavButtonContainer>
          <button>Home</button>
          <button>AddTask</button>
          <button>RecentTodo</button>
          <button>MyTodo</button>
        </NavButtonContainer>
      </FooterWrapper>
    </div>
  );
};

export default Footer;

문제점

footer가 컴포넌트 사이에 끼어있음

profile
Write a little every day, without hope, without despair ✍️

0개의 댓글