5월 23일(React, Blog 만들기)

JY·2022년 5월 23일
0
post-thumbnail

Blog 만들기

1. 글제목 state로 관리하기


state를 사용하는 이유?

  • 일반 변수는 갑자기 변경되면 HTML에 자동으로 반영되지 않는다.
  • state는 변경되었을 때, HTML이 자동으로 재렌더링된다.

👉 변동 시 자동으로 HTML에 반영되게 만들고 싶을 때 state를 사용하면 된다. (자주 변경될 것 같은 HTML 부분을 state로 만들어 놓자.)

let [글제목, b] = useState(['남자 코트 추천', '강남 우동맛집', '리액트독학']);

🤔 warning 메시지 없애는 기능
eslint-disable


2. 좋아요 기능


onClick 사용법

  • onClick={} 안에는 함수 이름을 넣어야 한다.

state 변경하는 법

  • 등호로 변경 금지(state = 1;)
  • state 변경 함수를 통해 state를 변경해야 한다.
    👉 state 함수를 사용하지 않으면 재렌더링이 되지 않는다.

let [따봉, 따봉변경] = useState(0);
<h4>{글제목[0]} <span onClick={() => {따봉변경(따봉+1)}}>👍</span> {따봉} </h4>

3. 글제목 변경 버튼


버튼을 하나 만들어서 누르면 '남자 코드 추천'이라는 글제목을 '여자 코드 추천'으로 변경하자.

❌ 잘못된 코드

let [글제목, 글제목변경] = useState(['남자 코트 추천', '강남 우동맛집', '리액트독학']);
<button onClick={() => {
  글제목[0] = '여자 코드 추천';
  글제목변경(글제목);
}}>글수정</button>

위와 같은 변경은 좋지 않을 뿐더러 작동도 하지 않는다.
array를 수정한 것이지 변수에 있던 화살표를 수정한 것이 아니다.


또한, array/object 다룰 때 원본은 보존하는 게 좋다.

⭕ 올바른 코드

<button onClick={() => {
  let copy = [...글제목];
  copy[0] = '여자 코트 추천';
  글제목변경(copy);
}}>글수정</button>

기존 state === 신규 state 경우 변경하지 않는다.
array/object를 담은 변수엔 화살표([1, 2, 3]이 어디 있는지 알려주는 화살표)만 저장된다.

let arr = [1, 2, 3];

글제목이라는 변수에 저장되어 있던 것은 화살표뿐이다.
따라서 let copy = 글제목은 화살표가 복사된 것이다.
변수1과 변수2의 화살표가 같으면 변수1 === 변수2의 결과값은 true가 나온다. (copy === 글제목true)

... -> 괄호 벗겨주세요


4. 상세페이지(모달)


<div>를 컴포넌트로 관리해보자.

컴포넌트 생성하기
1. function를 만든다.
2. return() 안에 HTML 코드를 담는다.
3. <함수명></함수명>
컴포넌트는 대문자로 시작한다!

function Modal() {
  return (
    <div className="modal">
      <h4>제목</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

🤔 어떤 걸 컴포넌트로 만들지?
1. 반복적인 HTML을 축약할 때
2. 큰 페이지들
3. 자주 변경되는 것들

컴포넌트의 단점: state 가져다 쓸 때 문제가 생긴다.


+) 글제목 누르면 모달창 나타나게 하기

🤔 동적인 UI 만드는 step
1. HTML/CSS로 미리 디자인 완성
2. UI의 현재 상태를 state로 저장
3. state에 따라 UI가 어떻게 보일지 작성


  1. HTML/CSS로 미리 디자인 완성
function Modal() {
  return (
    <div className="modal">
      <h4>제목</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

  1. UI의 현재 상태를 state로 저장
let [modal, setModal] = useState(false);

  1. state에 따라 UI가 어떻게 보일지 작성
{
  modal === true ? <Modal /> : null
}
  
<h4 onClick={() => {setModal(true);}}>{글제목[2]}</h4>

  • 리액트에서는 버튼을 누르면 모달창의 스위치(state)만 건드린다.
  • 자바스크립트였으면 버튼을 누르면 모달창 HTML을 직접 건드려야 한다.

+) 글제목 누르면 모달창 열리고, 다시 누르면 닫히기

처음에 1번 코드로 짰는데 2번 코드가 더 좋은 것 같다..!

//1
<h4 onClick={() => setModal(prev => !prev)}>{글제목[2]}</h4>

//2
<h4 onClick={() => setModal(!modal)}>{글제목[2]}</h4>

5. 반복문으로 HTML 축약


기존 코드

<div className="list">
  <h4>{글제목[0]} <span onClick={() => {따봉변경(따봉+1)}}>👍</span> {따봉} </h4>
    <p>217일 발행</p>
</div>
<div className="list">
  <h4>{글제목[1]}</h4>
<p>217일 발행</p>
</div>
<div className="list">
  <h4 onClick={() => setModal(prev => !prev)}>{글제목[2]}</h4>
<p>217일 발행</p>
</div>

map()

기존 코드를 map을 이용해서 다음처럼 축약할 수 있다.

글제목.map((item) => {
  return (
    <div className="list">
      <h4>{item} <span onClick={() => {따봉변경(따봉+1)}}>👍</span> {따봉} </h4>
    <p>217일 발행</p>
  </div>
  )
})

// i는 반복문 돌 때마다 0부터 1씩 증가하는 정수
글제목.map((item, i) => {
  return (
    <div className="list">
      <h4>{글제목[i]} <span onClick={() => {따봉변경(따봉+1)}}>👍</span> {따봉} </h4>
      <p>217일 발행</p>
    </div>
    )
})

🤔 warning
반복문으로 HTML을 생성하면 key를 줘야 함


🤔 콜백함수?
소괄호 안에 들어가는 함수를 콜백함수라고 한다.

🤔 map 기능?
1. array 자료 갯수만큼 함수 안의 코드를 실행해준다.
2. 함수의 파라미터는 array 안에 있던 데이터이다.
(a가 차례대로 1, 2, 3이 된다는 의미)

[1,2,3].map(function(a){
  console.log(a);
})
  1. return에 뭐 적으면 array로 담아준다.
    (array에 '123123'을 세 번 넣어준다는 의미)
[1,2,3].map(function(a){
  return '123123'
})

🤔 map() 동작원리
1. map() 쓰고나면 그 자리에 []가 남는다.
2. [<div>안녕</div>, <div>안녕</div>, <div>안녕</div>]가 남는다.

{
  [1,2,3].map(() => {
    return <div>안녕</div>
  })
}

+) 좋아요 state로 관리하기

map으로 HTML을 축약하고 나니, 좋아요를 관리하는 state가 하나라서 하나를 누르면 다른 좋아요도 함께 증가되는 현상이 발생한다. 따라서 따로따로 state를 만들어서 관리해야 한다.

let [따봉, 따봉변경] = useState([0, 0, 0]);

...

{
  글제목.map((item, i) => {
    return (
      <div className="list">
        <h4 onClick={() => {setModal(!modal)}}> {item} <span onClick={() => {
          let copy = [...따봉];
          copy[i] += 1;
          따봉변경(copy);
      }}>👍</span> {따봉[i]} </h4>
        <p>217일 발행</p>
  	  </div>
  	)
  })
}
profile
🙋‍♀️

0개의 댓글