- css 에 이미지 파일 경로 넣기
url('이미지경로');.main-bg{ /* ...(생략) */ background-image : url('./bg.png'); }
- html 안에서 src 폴더의 이미지 경로 넣기
이미지를 import 한 후 사용해야 함
외부 이미지 경로는 절대경로 그대로 작성하면 됨import bg from './bg.png' function App(){ return( <div> <div className="main-bg" style={{backgroundImage : 'url('+bg+')'}}></div> <img src={bg}> <img src="https://..."> </div> ) }
2. Public 폴더
1) 용도
여러가지 소스코드는 src 폴더에 보관하면 되는데
이미지같은 static 파일의 경우 public 폴더에 보관해도 됩니다.
리액트로 개발을 끝내면 build 작업이라는걸 하는데
지금까지 짰던 코드를 한 파일로 압축해주는 작업입니다.
src 폴더에 있던 코드와 파일은 다 압축이 되는데 public 폴더에 있는 것들은 그대로 보존해줍니다.
그래서 형태를 보존하고 싶은 파일은 public 폴더에 넣으면 되는데 js 파일은 그럴 일은 거의 없고
이미지, txt, json 등 수정이 필요없는 static 파일들의 경우엔 public 폴더에 보관해도 상관없습니다.2) public 폴더에 있는 이미지 사용할 때
- import 하지 않고, 그냥 /이미지경로 사용하면 됨
<img src='/이미지경로' />
- 권장되는 방식
<img src={process.env.PUBLIC_URL + '/이미지경로'} />
리액트로 만든 html 페이지를 배포할 때,라우트로 인해 경로가 바뀌게 되면 해당 이미지 파일을 찾을 수 없다고 나올 수 있기 때문에!
1. export default / import 문법
- 바인딩할 data를 다른 파일에 저장한 경우
(data.js 외부파일) let data = [...]; export default data;
(App.js 파일) import data from './data.js'; console.log(data);
- 유의점
- 변수, 함수, 자료형 전부 export 가능합니다.
- 파일마다 export default 라는 키워드는 하나만 사용가능합니다.
- 파일경로는 ./ 부터 시작해야합니다. 현재경로라는 뜻임
2. export{} / import {} 문법
- 여러개의 변수들을 내보내고 싶을 때
(data.js 파일) var name1 = 'Kim'; var name2 = 'Park'; export {name1,name2}
(App.js 파일) import {name1, name2} from './data.js';
- 유의점
- export { } 했던 것들은 import { } 쓸 때 자유작명이 불가능합니다. export 했던 변수명 그대로 적어야함
1. setting & 기본 라우팅
- 리액트는 html 파일을 하나만 사용함. 따라서 다른 페이지를 요청하면 내부에 있는
를 바꿔서 표출하면 됨. 이것을 도와주는 라이브러리가 react-router-dom
- npm install react-router-dom@6 설치
- index.js 파일에서
import { BrowserRouter } from "react-router-dom"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode> );
라우터로 페이지 나누는 법
(App.js) import {Routes, Route, Link} from 'react-router-dom' function App(){ return( // 생략 <Rotues> <Route path="/detail" element={<div></div>} /> <Route path="/home" element={<Component/>} /> </Routes> ) }
- 우선 상단에 여러가지 컴포넌트를 import 하고
<Routes>
를 만들고 그 안에<Route>
를 작성함<Route path="/url경로" element={<보여줄 html>}/>
페이지 이동 버튼 (Link)
<Link to="/">홈</Link>
- react-router-dom 에서 Link 컴포넌트를 import 한 후
- 원하는 곳에
<Link>
사용2. navigate
- 페이지 이동 기능을 만들고 싶다면 useNavigate()
import { Routes, Route, Link, useNavigate, Outlet } from 'react-router-dom' function App(){ let navigate = useNavigate() return( // 생략 <button onClick={()=>{navigate('/detail')}}></button> ) } ```
- useNavgiate() 함수를 쓰면 그 자리에 페이지 이동하는 함수가 남음.
- navigate('/detail') 작성하면 /detail 페이지로 이동가능
- navigate(-1) 등의 숫자를 넣으면 뒤로가기, 앞으로가기 가능. ex) navigate(1) 은 앞으로 1번, navigate(-1)은 뒤로 1번
- 404 페이지?
- 유저가 이상한 경로로 접속한 경우 "없는 페이지입니다" 를 띄우고 싶을 때
<Route path="*" element={<div>없는 페이지입니다.</div> } />
- 서브경로 만들 수 있는 nested routes
ex. "/about/member" 로 접속하는 페이지 등을 만들고 싶을 때<Route path = "/about" element={<About />}> <Route path="member" element={<div>멤버들</div>} /> <Route path="location" element={<div>회사위치</div} /> </Route>
- Route 안에 Route를 넣을 수 있는데, 이것을 Nested routes 라고 한다.
function About(){ return( <h4>About 페이지</h4> <Outlet></Outlet> ) }
<Outlet>
은 nested routes 안의 element 들을 어디에 보여줄지 표기하는 곳임.
그래서 이렇게 하면, /about/member 접속시 자리에 element 내의박스들이 보이게 된다.
참고) Styled-components 라이브러리
컴포넌트가 많은 경우, 스타일링을 하다보면 불편함이 많이 생김.따라서 스타일을 바로 입혀서 컴포넌트를 만들 수 있는 라이브러리가 styled-components 라이브러리이다.
npm install styled-components
로 설치 후,
import styled from 'styled-components'
import 후 사용하면 됨.기본적인 사용법
- 컴포넌트를 만들 때, 스타일을 미리 주입해서 만들 수 있다.
let Box = styled.div` padding:20px; color:grey `; function App(){ return ( <Box></Box> ) }
- 만들고 싶은 요소를
styled.div
같은 형식으로 만든다.- backtick 기호를 이용하여 CSS 스타일을 추가한다
- 그럼 그 자리에 컴포넌트를 남겨주는데, 그것을 변수에 저장해서 쓰면 된다.
- 추가 : props로 UI 재활용가능
let Box = styled.div` padding : 20px; color : ${props => props.color}; `; function App(){ return( <Box color = "orange" ></Box> <Box color = "grey" ></Box> ) }
- Component의 LifeCycle
1)생성이 될 수도 있고(mount)
2)재렌더링이 될 수도 있고(update)
3)삭제가 될 수도 있다.(unmount)
- 컴포넌트 lifecycle 중간중간 간섭할 수 있는데, 이를 lifecycle hook 이라고 함.
Lifecycle Hook
import {useState, useEffect} from 'react'; function App(){ useEffect(()=>{ console.log('안녕') }); return (생략) }
상단에서 useEffect를 import하고, 콜백함수 추가해서 안에 코드를 적으면 그 코드는 컴포넌트가 mount or update 될 시 실행된다.위 코드에서는 App 페이지 로드시 콘솔창에 '안녕' 이 출력되게 됨.
참고) '안녕' 2번 출력되는데?
index.js에서 <React.StrictMode>라는 태그를 삭제하면 됨
참고2) useEffect 바깥에 코드 적어도 똑같이 실행되는데?컴포넌트가 mount&update시 function 안에 있는 코드도 다시 읽고 지나가서 그렇다. 그렇다면 useEffect를 언제 사용해야 하나?
- useEffect 안에 적은 코드는 html 렌더링 후에 작동한다. 예를 들어 굉장히 시간이 오래걸리는 코드가 필요하다고 하면, useEffect 안에 적어주면 html 렌더링 후에 작동하므로 좀 더 html 렌더링이 빠른 사이트를 원할 때 사용가능하다.
즉, 컴포넌트의 핵심 기능은 html 렌더링이라, 외의 기능은 useEffect 안에 적는 것이 좋다.( ex. 오래 걸리는 반복 연산, 서버에서 데이터를 가져오는 작업, 타이머 함수 등)
- useEffect
useEffect(()=>{실행할 코드},[변수]);
useEffect의 두번째 파라미터로 []를 넣을 수 있는데, 여기에 변수나 state를 넣을 수 있다. 이는 []안에 있는 변수나 state가 변할 때만 useEffect안의 코드를 실행하는 것을 뜻한다.
useEffect(()=>{실행할코드},[])
[] 안에 아무것도 넣지 않으면, 컴포넌트가 mount시(로드시) 1회만 실행하고 영영 실행하지 않는다.useEffect(()=>{ 2.그 다음 여기 코드가 실행됨 return()=>{ 1.여기 있는 코드가 먼저 실행됨 } },[변수])
useEffect 동작 전 특정 코드를 실행하고 싶다면,
return()=>{}
안에 넣으면 된다.이를 clean up function 이라고 함. clean up function 안에는 타이머제거,socket 연결요청제거, ajax 요청 중단 등의 코드를 많이 작성함.useEffect(()=>{ let a = setTimeout(()=>{ setAlert(false) }, 2000) return ()=>{ clearTimeout(a) } }, [])
!!정리
1.
재렌더링마다 코드를 실행하고 싶을 때,
useEffect(()=>{실행할 코드})
2.컴포넌트 mount시(로드시) 1회만 실행하고 싶을 때
useEffect(()=>{실행할 코드},[])
3.useEffect안의 코드 실행 전, 특정 코드 실행하고 싶을 때useEffect(()=>{ return()=>{ 실행할 코드 } })
4.컴포넌트 unmount시 1회만 실행하고 싶을 때
useEffect(()=>{ return ()=>{ 실행할코드 } }, [])
- state1이 변경될 때만 실행하고 싶을 때
useEffect(()=>{실행할 코드} ,[state1]) ``
서버에 Get,Post 요청을 할 때, 새로고침 없이 데이터를 주고받을 수 있게 도와주는 기능.
방법이 3가지 있다.
1. XMLHttpRequest(옛날 문법)
2. fetch() (최신 문법)
3. axios 라이브러리AJAX 요청하는 법
import axios from 'axios' function App(){ return ( <button onClick={()=>{ axios.get('url').then((res)=>{ console.log(res.data) }) .catch(()=>{ console.log('실패함') }) }}>버튼</button> ) }
1.axios import
2.axios.get(URL) : 해당 URL로 get 요청
3.res : 서버에서 보내주는 데이터
4..catch()
: ajax 통신 실패했을 때 실행될 코드
Post 요청하는 법
axios.post('URL',{name:'Kim'}).then(완료시 실행하고 싶은 코드).catch(실패했을 때 실행하고 싶은 코드);
동시에 AJAX 요청 여러개 보내고 싶을 때
Promise.all([axios.get('URL')],[axios.get('URL2')])
Fetch() 사용하기
fetch('URL').then(result=>result.json()).then((result)=>{console.log(result)})
fetch() 함수는 javascript 내장 함수. json형식을 object/array 변환작업 해줘야 함.(.json)
참고) Axios 라이브러리는 Json->object/array 변환작업을 자동으로 해줌.