🗝 Keywords
✅ styled-components로 스타일 입히기
✅ useEffect를 활용하여 구매이벤트 만들기
✅ ajax 통신으로 데이터 끌어오기
✅ 더보기 버튼으로 데이터 끌어오기
✅ 로딩 spinner 구현하기
✅ 데이터 보내기(post)
🚀 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의 장점
- 해당 컴포넌트에만 적용할 수 있음
- css를 작성하면 react는 싱글페이지 어플리케이션이기 때문에 html,js,css를 모두 합친다. 그렇기 때문에 app.js에만 적용하고 싶어서 거기에 작성을 해도 모든 컴포넌트에 적용이 된다.
- 이를 방지하기 위해서는 css를 모듈화해야함 App.module.css 이런식으로 파일명을 만들고 App.js에서 import하면 해당 컴포넌트에만 적용이됨
- 위와 같이 특정 컴포넌트에만 css를 입히고 싶을 때 번거롭지 않게 작성할 수 있음
- 로딩시간 단축이 가능함 (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 하는 사람이 해당 문법에 익숙하지 않으면 사용에 어려울 수 있음
🚀 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을 활용해서 진행하면 된다.
🚀 백엔드에서 추가 상품데이터를 반영해달라고 한다면?
- 서버와 통신하는 것은 (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를 하면 됨.
🚀 더보기 버튼 만들기
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을 띄어주기로 했다.
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로 해줬다.
🚀 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을 사용할 수 있다.