패스트캠퍼스 메가바이트스쿨 Day 35 (7주차 금요일) - React로 쇼핑몰 만들기 (4)

ctaaag·2022년 5월 31일
0
post-thumbnail

Today Topic : React로 쇼핑몰 만들기 (4)


🗝 Keywords

✅ styled-components로 스타일 입히기

✅ useEffect를 활용하여 구매이벤트 만들기

✅ ajax 통신으로 데이터 끌어오기

✅ 더보기 버튼으로 데이터 끌어오기

✅ 로딩 spinner 구현하기

✅ 데이터 보내기(post)



1. styled-components이용해서 결제버튼 만들기

🚀 styled-components 기본구조

npm install styled-components
import styled from "styled-components";
let YellowBtn = styled.button`
  background: yellow;
  color: black;
  padding: 10px;
`;

let Box = styled.div`
  background: grey;
  padding: 20px;
`;

  export default function Detail(props) {
  let { id } = useParams();
  if (id < props.product.length) {
    return (
      <>
        <Box>
          <YellowBtn>버튼</YellowBtn>
        </Box>
      </>
  • styled components를 위와 같이 설치하고, import를 하면 사용할 수 있음.
  • let 변수명 = styled.html요소 style 이런식으로 작성하면 스타일을 입힌 요소가 만들어짐

🚀 styled-components의 장점

    1. 해당 컴포넌트에만 적용할 수 있음
  • css를 작성하면 react는 싱글페이지 어플리케이션이기 때문에 html,js,css를 모두 합친다. 그렇기 때문에 app.js에만 적용하고 싶어서 거기에 작성을 해도 모든 컴포넌트에 적용이 된다.
  • 이를 방지하기 위해서는 css를 모듈화해야함 App.module.css 이런식으로 파일명을 만들고 App.js에서 import하면 해당 컴포넌트에만 적용이됨
    1. 위와 같이 특정 컴포넌트에만 css를 입히고 싶을 때 번거롭지 않게 작성할 수 있음
    1. 로딩시간 단축이 가능함 (html에 style 태그를 생성하기 때문)

🚀 props를 통한 재사용 가능

let YellowBtn = styled.button`
  background: ${(props) => (props.primary ? "white" : "palevioletred")};
  color: ${(props) => (props.primary ? "palevioletred" : "white")};
  padding: 10px;
  margin: 3px;
  border-radius: 6px;
  border: 2px solid palevioletred;
`;

let NewBtn = styled(YellowBtn)`
  background: ${(props) => props.bg};
  color: ${(props) => (props.bg == "blue" ? "white" : "black")};
  border-color: white;
  margin-left: 20px;
`;

let Box = styled.div`
  background: grey;
  padding: 20px;
`;

export default function Detail(props) {
  let { id } = useParams();
  if (id < props.product.length) {
    return (
      <>
        <Box>
          <YellowBtn primary>장바구니담기</YellowBtn>
          <YellowBtn>찜하기</YellowBtn>
          <NewBtn bg="blue">결제하기</NewBtn>
          <NewBtn bg="red">추천하기</NewBtn>
        </Box>
      </>
    );
  • styled-component의 가장 큰 장점은 위와 같이 props를 인자로 넘겨서 재사용성을 확장한다는 것이다.
  • 위와 같이 ${props}로 특정 변수 자체를 넘기거나, 변수에 내가 원하는 값을 넣어서 거기에 맞는 스타일을 출력하는 것도 가능함
  • 비슷한 스타일을 입히고 싶은 경우에는 NewBtn 변수처럼 작성하면 스타일 복제도 가능함.

🚀 styled-components의 단점

  • 컴포넌트 js파일이 더러워짐..
  • 다른 컴포넌트에서 사용하려면 import써서 사용해야해서 이부분은 사실 그냥 css랑 별반 차이없음
  • css 하는 사람이 해당 문법에 익숙하지 않으면 사용에 어려울 수 있음

2. useEffect활용하여 구매이벤트 추가하기

🚀 useEffect에서 자주 사용하는 것

  • useEffect는 html요소들을 먼저 렌더하고 나중에 시작함.
    그래서 보통 시간이 오래걸리는 작업을 걸어놓는다. 보통은 어려운 연산,서버에서 데이터 가져오는 작업,타이머 장착하는 것을 이렇게 작성함

🚀 구매이벤트 추가

  const [fade, setFade] = useState(true);

  useEffect(() => {
    setTimeout(() => {
      setFade(false);
    }, 2000);
  }, []);

    return (
      <>
        {fade === true ? (
          <EventDiv className="event_div">2초 이내에 구매시 30% 할인</EventDiv>
        ) : null}
  • 위와 같이 구매이벤트 창을 2초뒤에 없애고 싶다면 위와 같이 정의를 해주면 된다.

🚀 구매수량 입력버튼에 텍스트를 입력했을 경우 alert뜨게 하기

  useEffect(() => {
    if (isNaN(value) == true) {
      alert("숫자만 입력하세요");
      setValue("");
    }
  }, [value]);

  const handleChange = (e) => {
    setValue(e.target.value);
  };

<input placeholder="숫자를 입력하세요" onChange={handleChange} />
  • 숫자가 아닌지 확인하는 것은 isNan을 활용해서 진행하면 된다.

3. ajax 활용

🚀 백엔드에서 추가 상품데이터를 반영해달라고 한다면?

  • 서버와 통신하는 것은 (get 요청, post 보내기) 두 가지 방식있다.
  • 예를 들어, 사용자가 네이버블로그(naver.blog.com) 주소를 get 요청을 하면 해당 데이터를 보내주는 형태
  • get 요청을 하는 가장 간단한 방법은 웹페이지에 주소를 입력하는 것(다만, 새로고침이 진행됨)
  • 자바스크립트에서는 ajax를 통해서 새로고침 없이 get 요청을 할 수 있음

🚀 자바스크립트에서 ajax 사용법

  • ajax 사용법은 크게 3가지가 있다. 옛날 자바스크립트 문법(XMLHttpRequest), 요즘 자바스크립트 문법(fetch()), 외부 라이브러리(axios)가 있음.
  • 가장 간편하고 관리가 쉬운 것은 axios이므로, axios를 중심으로 사용할 예정.

🚀 axios 사용법

npm install axios
import axios from 'axios'

<button
onClick={() => {
  axios
    .get("서버주소")
    .then((data) => {
	console.log(data.data)
  })
    .catch(() => {
    alert("실패함");
  });
}}

    더보기
</button>
  • axios는 npm install 후에 사용하고자 하는 페이지에서 import를 한다.
  • 그 다음에 axios를 불러올 엘리먼트 혹은 컴포넌트로 만들어 놓으면 된다.
  • axios.get("서버주소").then((변수)=>{data로 받아와서 할 행동})
  • 만약 실패시에 특정 행동을 하고 싶다면 .catch를 하면 됨.

4. axios 활용해서 더보기버튼 만들기

🚀 더보기 버튼 만들기

axios
  .get(
  `https://raw.githubusercontent.com/ctaaag/shoppingmall/main/shopdata0.json`
  )
  .then((data) => {
  let copy = [...newproduct, ...data.data];
  setNewproduct(copy);
  })
  .catch(() => {
  alert("더 이상 제품이 없습니다");
  setLoding(null);
  });
  • 위와 같이 더보기 버튼을 누르면 기존 상품데이터에 data를 합쳐서 copy본을 만들고 제품을 보여주는 코드를 짰다.
  • 위와 같이 나오게 된다.
  • 근데 여기서 더보기 버튼을 한 번 더 눌렀을 때 다음데이터를 넣으려면 어떻게 해야할까?
  • 데이터 주소 링크를 클릭 횟수에 따라서 다르게 하면 된다.
axios
  .get(
  `https://raw.githubusercontent.com/ctaaag/shoppingmall/main/shopdata${clicknum}.json`
  )
  .then((data) => {
  let copy = [...newproduct, ...data.data];
  setNewproduct(copy);
  setLoding(null);
  })
  .catch(() => {
  alert("더 이상 제품이 없습니다");
  setLoding(null);
  });
setClicknum(clicknum + 1);
}}
  • 그래서 위와 같이 clicknum이라는 useState를 만들고 axios 클릭마다 num을 붙이기로 했다. 그리고 num에 해당하는 데이터를 끌고 오기 위해 데이터에 ${clicknum}으로 주소값을 계속 바꿔 줬다.
  • 그리고 캐치를 이용해서 없는 데이터를 끌고 오게 되면 더 이상 제품이 없다고 alert을 띄어주기로 했다.

5. 로딩 spinner 구현하기

  const [loading, setLoading] = useState(null);

  const Loadingicon = () => {
    return (
      <Spinner animation="border" role="status">
        <span className="visually-hidden">Loading...</span>
      </Spinner>
    );
  };

<div>{loding}</div>
<button
onClick={() => {
  setLoding(Loadingicon());
  axios
    .get(
    `https://raw.githubusercontent.com/ctaaag/shoppingmall/main/shopdata${clicknum}.json`
  )
    .then((data) => {
    let copy = [...newproduct, ...data.data];
    setNewproduct(copy);
    setLoading(null);
  })
    .catch(() => {
    alert("더 이상 제품이 없습니다");
    setLoading(null);
  });
  setClicknum(clicknum + 1);
}}
  >
    더보기
</button>
</Container>
);
}

🚀 loading spinner 구현하기

  • 위와 같이 spinner를 리액트 부트스트랩을 이용해서 디자인을 가져왔고
  • 버튼 위에 초기값을 null로 한 usestate loading 값을 적용하고
  • axios get 버튼을 누르고 데이터를 끌어오면 setLoading을 null로 해줬다.

6. 기타 axios 주요 내용

🚀 axios로 post(데이터 보내기)
axios.post('/fff', {name : 'kim'})

  • 이런식으로 axios 데이터를 보낼 수 있다.
  • 원래는 데이터로 배열, 객체는 보낼 수 없으나 문자열로 변환하면 가능함.
  • 이를 json데이터라고 하는데, js문법인 fetch는 다 하나씩 수정을 해줘야하나 axios는 그냥 배열,객체 형태로 보내면 자동으로 변환을 해줌

🚀 Promise.all

Promise.all([ axios.get('/url1'), axios.get('/url2')
.then(()=>{
	두개 데이터 모두 성공했을 때 함수 실행
})
  • promise.all을 통해서 여러가지 데이터를 한번에 받아와서 그 결과에 대한 then을 사용할 수 있다.
profile
프로그래밍으로 지속가능한 세상을 꿈꾸며

0개의 댓글