티스토리 뷰
[React] React 리액트 기초부터 쇼핑몰 프로젝트까지! (Part 1 : 블로그 제작 & 기초 문법)
무화과(Fig) 2022. 8. 2. 20:36기초 2강
1. 태그에 class를 주고 싶으면?
class 대신 className 작성하기
2. 리액트가 HTML 코딩보다 편리한 이유
1) 데이터 바인딩이 쉬움(데이터 바인딩이 쉬운 React, Vue, Angular)
<h4>{ posts }</h4> // {변수명}
- 렌더링 시켜주면 됨
- scr, id, href 등의 속성에서도 {변수명, 함수} 등 넣어주면 됨
<img src={logo} />
3. JSX 에서 style 속성 집어넣을 때 style = {object 자료형으로 만든 스타일}
<div style={{color:'blue', fontSize: '30px'}}>개발 Blog</div> // camelCase로 작성하기
기초 3강
- 데이터 보관법:
1. 변수에 넣거나
2. state에 넣거나
- ES6 destructuring
- state:
1) 변수 대신 쓰는 데이터 저장공간
2) useState()를 이용해 만들어야 함
let [글제목, 글제목변경] = useState('여자 코트 추천');
// useSate('여자 코트 추천') = [state 데이터, state 데이터 변경 함수]
- 그럼 변수 쓰면 되는데 왜 굳이 state를 만드느냐?
state에 데이터를 저장해놓는 이유는 웹이 app처럼 동작하게 만들고 싶어서이다.
그냥 변수는 값이 변경되어도 자동 리랜더링이 안된다. 그러나 state로 만들어놓은 데이터는 HTML이 새로고침 없이도 리렌더링을 해준다. (스무스하게 변경됨)
따라서 자주 바뀌고, 중요한 데이터는 변수말고 state로 저장해서 써야함
기초 4강
- 이벤트 다루는법
1) onClick ={ 클릭될 때 실행할 함수}
2) onClick = {()=>{실행할 내용}}
- 리액트는 이뮤터블임. 원본 데이터를 직접 수정하면 상태값 관리가 매우 힘들어지기 때문임
- 리액트 대 원칙: immutable data
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=rhkrehduq&logNo=221349310339
- 버튼 클릭시 남자코트추천을 여자코트추천으로 변경하는 방법
1) 수정된 <데이터>를 만든다. (*state의 복사본을 만들어서 수정하기(deep copy하기))
*deep copy란?
값 공유를 하지 않고 완전히 새로운 복사본 하나를 만드는 것!
왜 이런짓을 할까?
리액트는 원본 데이터를 직접 수정하면 상태값관리가 매우 힘들어지기 때문이다.
잘못된 예시
function App() {
let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동 맛집', '리액트 독학']);
let [따봉, 따봉변경] = useState(0);
function 제목바꾸기() {
let newArr = 글제목; // 이건 복사가 아니라 공유임(reference data type 참고하기)
newArr[0] = '여자 코트 추천';
글제목변경(newArr);
}
옳은 예시
function App() {
let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동 맛집', '리액트 독학']);
let [따봉, 따봉변경] = useState(0);
function 제목바꾸기() {
let newArr = [...글제목]; // spread opertor를 이용해 복사하기. (객체도 이런식으로 복사하기)
newArr[0] = '여자 코트 추천';
글제목변경(newArr);
}
<정리>
- Array, Object state 데이터 수정 방법
1) 일단 변경함수(대체할 데이터)를 써야함
* state는 직접 건들면 안됨. 왜? 리렌더링이 되지 않을 수 있음.
2) 복사본을 하나 만들기
3) 복사본을 바탕으로 변경하기
4) 변경함수를 이용해 변경하기.
5강-모달 창 만들기
- 여러개의 연속된 tag들은 만들 수 없음
return {
<div></div>
<div></div>
<div></div>
}
- HTML을 한 단어로 줄여서 쓸 수 있는 방법: 리액트의 Component 문법
- Component 만드는 방법
function App() {
let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동 맛집', '리액트 독학']);
let [따봉, 따봉변경] = useState(0);
return (
<div className="App">
<div className='black-nav'>
<div>개발 Blog</div>
</div>
{/* <button onClick={제목바꾸기}>버튼</button> */}
<div className='list'>
<h3>{ 글제목[0] } <span onClick={ () => {따봉변경(따봉 + 1)} }>따봉</span> {따봉} </h3>
<p>2월 17일 발행</p>
<hr/>
</div>
<div className = 'list'>
<h3>{글제목[1]}</h3>
<p>2월 18일 발행</p>
<hr/>
</div>
<div className = 'list'>
<h3>{글제목[2]}</h3>
<p>2월 19일 발행</p>
<hr/>
</div>
<Modal></Modal> // => <Modal />이렇게 써도 됨.
</div>
);
}
function Mdoal() {
return (
<div className='modal'>
<h2>제목</h2>
<p>날짜</p>
<p>상세 내용</p>
</div>
)
}
// Component 만드는 방법
// 1. 함수 만들고 이름 짓고(Modal)
// 2. 축약을 원하는 HTML에 넣고
// 3. 원하는 곳에 <함수명 /> 넣기
- Component 유의사항
1. 이름은 대문자로 시작하기
2. return() 안에 있는건 태그 하나로 묶어야 함( ex. div 태그로 묶기)
* div를 쓰기 싫으면 <></>로 묶으면 됨
function Mdoal() {
return (
<>
<div className='modal'>
<h2>제목</h2>
<p>날짜</p>
<p>상세 내용</p>
</div>
<div></div>
</>
)
}
*중요*
<동적인 UI 만드는 step >
1. html,css 로 미리 디자인 완성
2. UI의 현재 상태를 state로 저장
3. state에 따라 UI가 어떻게 보일지 작성
- 모달창 만들기
방법1)
import React, { useState } from 'react';
import logo from './logo.svg';
import './App.css';
function App() {
let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동 맛집', '리액트 독학']);
let [따봉, 따봉변경] = useState(0);
let[modal, setModal] = useState(false);
function 누르면여자코트로바뀐다 () {
let newArr = [...글제목];
newArr[0] = '여자 코트 추천';
글제목변경(newArr);
}
return (
<div className="App">
<div className='black-nav'>
<div>개발 Blog</div>
</div>
<button onClick={누르면여자코트로바뀐다}>버튼</button>
<div className='list'>
<h3>{글제목[0]} <span onClick={()=> {따봉변경(따봉 + 1)}}>따봉눌러줫</span> {따봉}</h3>
<p>2/18</p>
<hr/>
</div>
<div className='list'>
<h3>{글제목[1]}</h3>
<p>2/19</p>
<hr/>
</div>
<div className='list'>
<h3 onClick={() => modal == true ? setModal(false) : setModal(true)}>{글제목[2]}</h3>
// 삼항연산자를 이용해 모달창 만듦
<p>2/20</p>
<hr/>
</div>
{
modal == true ? <Modal /> : null
}
</div>
)
};
function Modal(){
return (
<div className='modal'>
<h2>제목</h2>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
export default App;
방법2)
function App (){
let [modal, setModal] = useState(false);
return (
<div>
(생략)
<button onClick={ ()=>{ setModal(!modal) } }> {글제목[0]} </button>
{
modal == true ? <Modal></Modal> : null
}
</div>
)
}
느낌표는 느낌표 우측 자료를 반대로 바꿔줌
(!true는 출력해보면 false임, !false는 출력해보면 true임)
map : 많은 div들을 반복문으로 줄이고 싶은 충동이 들 때 사용
비슷한 html 반복생성을 하려면 map()을 쓰면 됨
map 함수
1.array 자료 갯수만큼 함수안의 코드를 실행해줌
2. 함수의 파라미터는 array안에 있던 자료임
3. return에 뭐 적으면 array로 담아줌
예제
{
글제목.map(function(a , i){
return (
<div className='list'>
<h3>{ 글제목[i] } <span onClick={()=> {따봉변경(따봉 + 1)}}>따봉눌러줫</span>{따봉}</h3>
<p>2/19</p>
<hr/>
</div>
)
})
}
1) 글제목은 array임
2) a는 array 안의 파라미터임
3) i는 정수임 ex 글제목[1] => 강남 우동 맛집
반복된 HTML에 각각 다른 제목을 부여하고 싶다면
let [따봉, 따봉변경] = useState([0, 0, 0]);
{
글제목.map(function(a, i) {
return (
<div className='list'>
<h3>
{ 글제목[i] } <span onClick={() => {
let copy = [...따봉];
copy[i] = copy[i] + 1;
따봉변경(copy);
}}>따봉눌러줫</span>{따봉[i]}
</h3>
<p>2/19</p>
<hr />
</div> )
})
}
자식이 부모의 state 가져다쓰고 싶을 때 props 사용
부모 -> 자식 state 전송하는 법? props 문법 쓰면 됨
1. <자식컴포넌트 작명 = {state이름}>
2. props 파라미터 등록 후 props.작명 사용
예제
{1.
modal == true ? <Modal 글제목={글제목}/> : null // 1. 작명 = {state 이름}
}
</div>
)
}
function Modal(props){ // 2. props 문법 쓰면 됨
return (
<div className='modal'>
<h2>{props.글제목[0]}</h2> // 3. props 파라미터 등록 후 props.작명 사용
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
*주의사항
- props 전송은 부모-> 자식만 가능.(자식->부모는 불가)
- 자식 & 자식 컴포넌트끼리 전송 불가
모달 색 바꾸기
{
modal == true ? <Modal color={"blue"} 글제목={글제목}/> : null
}
</div>
)
}
function Modal(props){
return (
<div className='modal' style={{background: props.color}}>
<h2>{props.글제목[0]}</h2>
<p>날짜</p>
<p>상세내용</p>
</div>
)
}
- 제목 클릭하면 모달에 뜨게 하는 예제(1번 제목클릭하면 1번 글제목이 뜸)
function App() {
// state만드는 곳은 state 사용하는 컴포넌트들 중 최상위 컴포넌트임
let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동 맛집', '리액트 독학']);
let [따봉, 따봉변경] = useState([0, 0, 0]);
let[modal, setModal] = useState(false);
let [title, setTitle] = useState(0);
return (
<div className="App">
<div className='black-nav'>
<div>개발 Blog</div>
</div>
{
글제목.map(function(a, i) {
return (
<div className='list'>
<h3 onClick={() => {setModal(true); setTitle(i); }}>
{ 글제목[i] } <span onClick={() => {
let copy = [...따봉];
copy[i] = copy[i] + 1;
따봉변경(copy);
}}>따봉눌러줫</span>{따봉[i]}
</h3>
<p>2/19</p>
<hr />
</div>
)
})
}
{
modal == true ? <Modal title={title} 글제목={글제목}/> : null
}
</div>
)
}
function Modal(props){
return (
<div className='modal'>
<h2>{ props.글제목[props.title] }</h2>
<p>날짜</p>
<p>상세내용</p>
<button>글수정</button>
</div>
)
}
input 1 : 사용자가 입력한 글 다루기
암기할 것: state 만드는 법, props 전송하는 법, 컴포넌트 만드는 법, UI 만드는 step
-<input>에 입력한 값 가져오는 법
<input onChange={(e)=>{ console.log(e) }} /> // e는 객체라고 보통 부름. input태그에서 발생하는 이벤트에 관련한 여러 기능이 담겨있음.
-클릭 이벤트는 상위html로 퍼짐.(이벤트 버블링)
따라서 span태그를 눌러도 모달창이 열림.
{
글제목.map(function(a, i) {
return (
<div className='list'>
<h3 onClick={() => {setModal(true); setTitle(i);}}>
{ 글제목[i] } <span onClick={() => {
let copy = [...따봉];
copy[i] = copy[i] + 1;
따봉변경(copy);
}}>따봉눌러줫</span>{따봉[i]}
</h3>
<p>2/19</p>
<hr />
</div>
)
})
}
따라서 이벤트 버블링을 막기 위해서는 e.stopPropagation()을 사용해야함. (자바스크립트 문법임. 리액트 전에 자바스크립트를 잘 해야하 하는 이유)
{
글제목.map(function(a, i) {
return (
<div className='list'>
<h3 onClick={() => {setModal(true); setTitle(i);}}>
{ 글제목[i] } <span onClick={(e) => { e.stopPropagation();
let copy = [...따봉];
copy[i] = copy[i] + 1;
따봉변경(copy);
}}>따봉눌러줫</span>{따봉[i]}
</h3>
<p>2/19</p>
<hr />
</div>
)
})
}
-(정보) state 변경함수는 늦게 처리됨(비동기처리)
따라서 콘솔창을 보면 맨 첫줄은 빈 줄임
<input onChange={(e)=>{
입력값변경(e.target.value); // 이거 완료되기 전에
console.log(입력값); // 다음줄을 실행해줌
}} />
input 다루기 2 : 블로그 글발행 기능 만들기
array 형태의 state 조작은 우선 카피부터하면 됨
<input onChange={(e)=>{
입력값변경(e.target.value);
console.log(입력값);}} />
<button onClick={() => {
let copy글발행 = [...글제목]; // 글제목state를 우선 카피함
copy글발행.unshift(입력값); // array 자료 맨 앞에 자료추가하는 문법
글제목변경(copy글발행); // state 변경함수 사용
}}>글발행</button>
class를 이용한 옛날 React 문법
- 컴포넌트 만들 때 function 쓰면 됨. 예전 리액트에선 class 문법을 사용 했었음. 지금은 그냥 function 쓰라고 권장하기 때문에 참고만 해도 됨.
- class문법 매우쉽게 설명: 변수랑 함수를 많이 보관할 수 있는 곳
constructor, super, render 채워넣어야 함.
class Modal2 extends React.Component {
constructor(){
super()
}
render(){
return(
<div>안녕</div>
)
}
}
- class 컴포넌트에서 state 만드려면
class Modal2 extends React.Component {
constructor(){
super();
this.state = { // object 안에 넣으면 됨
name: 'Jane',
age: 20
}
}
render(){
return(
<div>안녕</div>
)
}
}
- state 쓰는 법
<div>안녕 {this.state.name}</div>
- state 변경하는 법
기존 state를 갈아치워주는게 아니라 변경해줌
return(
<div>안녕 {this.state.age}
<button onClick={()=> {
this.setState({age: 21})
}}>버튼</button>
</div>
)
-class 컴포넌트에서 props 이용하는 법
class Modal2 extends React.Component {
constructor(props){ // props
super(props); // props
this.state = {
name: 'Jane',
age: 20
}
}
render(){
return(
<div>안녕 {this.props} // props
<button onClick={()=> {
this.setState({age: 21})
}}>버튼</button>
</div>
)
}
}
'Online courses > Coding apple' 카테고리의 다른 글
[React] React 리액트 기초부터 쇼핑몰 프로젝트까지! (Part 2 : 쇼핑몰 프로젝트) (0) | 2022.08.18 |
---|---|
[React] React 리액트 기초부터 쇼핑몰 프로젝트까지! (Part 2 : 쇼핑몰 프로젝트) ( ~리액트에서 탭 UI 만들기) (0) | 2022.08.11 |
- Total
- Today
- Yesterday
- map
- js
- Target
- 객체
- CSS
- 비동기
- arguments
- 프론트엔드
- 제어 컴포넌트
- 동기
- rest parameter
- innerhtml
- GitHub
- 비제어 컴포넌트
- html
- 코드잇 스프린트
- 취업까지달린다
- react
- tanstackquery
- javascript
- 중급 프로젝트
- hydrationboundary
- Git
- 스프린트프론트엔드6기
- currentTarget
- 배열
- 리액트
- 코드잇스프린트
- 유사배열객체
- Next.js
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |