리액트

리액트> props를 응용한 상세페이지 만들기

연습노트 2024. 7. 18. 11:26

Q. 지금 누른 글제목이 모달창안에 뜨게 하고 싶으면 어떻게 코드를 짜야할까요?

0번 글을 누르면 0번 글제목이 모달창안에 등장하고

1번 글을 누르면 1번 글제목이 모달창안에 등장하고

그런 식으로 동작하게 만들어봅시다. 

다 배운내용이라 강의 듣지말고 알아서 해봅시다. 

 

 

약간의 힌트는 

 

직접 뭐라도 해보라고 드리는 힌트인데 

모달창안의 제목도 일종의 동적인 UI입니다. 

동적인 UI 어떻게 만들라고 했습니까 

 

1. html css로 미리 디자인해놓고 

2. 현재 UI의 상태를 state로 만들어두고

3. state 종류에 따라서 UI가 어떻게 보일지 작성하랬습니다. 

그러면 끝임 

이제 나중에 필요할 때 스위치 (state) 조작만 하면 됩니다. 

 

 

 

 

 

 

1. html css로 미리 디자인해놓고 

 

다 한것 같군요 패스합시다 

 

 

 

 

2. 현재 UI의 상태를 state로 만들어두고

 

let [title, setTitle] = useState(0);

그래서 저는 function App(){} 안에 state 하나 만들었습니다. 

모달창 안의 글제목은 0번글이 보이거나 1번글이 보이거나 2번글이 보이거나 

이런 상태밖에 없어서 그냥 숫자로 표현하고 싶어서 숫자적어놨습니다. 

 

 

 

 

3. state에 따라서 UI가 어떻게 보일지 작성

 

function App (){
  let [title, setTitle] = useState(0);
  (생략)
}

function Modal(props){
  return (
    <div className="modal">
      <h4>{ 만약에 title == 0이면 0번 글제목 보여주세요~ }</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  )
}

만약에 title == 0이면 props.글제목[0] 보여주세요~

만약에 title == 1이면 props.글제목[1] 보여주세요~

이렇게 코드짜면 기능완성입니다. 

당연히 조건문 같은거 사용하면 됩니다.

 

 

 

function App (){
  let [title, setTitle] = useState(0);
  (생략)
}

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

근데 이렇게 해도 될듯요 

그럼 title이 0이면 props.글제목[0] 보이지 않겠습니까 

아무튼 기능완성인데 왜 에러가 나는 것이죠

 

왜겠습니까

 

title이라는 state는 부모가 가진 state라서 

자식이 사용하고 싶으면 props로 전송해야합니다. 전송하십시오 

 

 

function App (){
  let [title, setTitle] = useState(0);
  (생략)
  {
    modal == true ? <Modal title={title} 글제목={글제목} /> : null
  }
}

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

props로 전송했습니다. UI 만들기 끝 

이제 스위치를 다 만들어놨기 때문에

title이라는 스위치를 0, 1, 2로 바꿔주면 그 때마다 알맞은 글이 모달창에 표시됩니다.

 

[collapse]

 

 

 

글에 onClick 집어넣으면 끝임 

 

이제 글을 클릭할 때 스위치만 샤샥 바꿔주면 원하는 기능구현 끝입니다.

0번 글을 클릭하면 title이라는 스위치를 0으로 바꿔주고

1번 글을 클릭하면 title이라는 스위치를 1로 바꿔주고

2번 글을 클릭하면 title이라는 스위치를 2로 바꿔주고

그러면 의도한 기능이 완성되겠군요.

 

근데 지금 글제목들이 map 반복문으로 복잡하게 생성되어있기 때문에

반복문 무서워할까봐 반복문 없앤 버전으로 한번 먼저 시도해봅시다. 

 

 

 

 

function App (){
  let [title, setTitle] = useState(0);
  return (
    <div>
      <button onClick={()=>{ ? }}> 0번글 </button>
      <button onClick={()=>{ ? }}> 1번글 </button>
      <button onClick={()=>{ ? }}> 2번글 </button>
      <Modal 어쩌구/>
    </div>
  )
}

버튼 3개를 만들어봤는데 이걸 각각의 글제목이라고 간주하고 여기에 코드를 짜보도록 합시다. 

0번 글을 누르면 title이라는 state를 0으로 바꿔주면 어떻게하죠? 

 

 

 

function App (){
  let [title, setTitle] = useState(0);
  return (
    <div>
      <button onClick={()=>{ setTitle(0) }}> 0번글 </button>
      <button onClick={()=>{ setTitle(1) }}> 1번글 </button>
      <button onClick={()=>{ setTitle(2) }}> 2번글 </button>
      <Modal 어쩌구/>
    </div>
  )
}

이러면 될듯요 매우 쉽습니다.

그럼 이제 버튼 누를 때 마다 state가 잘 바뀝니다.

state가 바뀌면 모달창안의 제목도 알아서 잘 바뀌고요.

이제 연습은 끝났고 map 반복문안에 있는 제목도 저거랑 비슷하게 수정하면 될듯요 

 

 

 

저는 어떻게 했냐면

 

function App (){
  return (
    <div>
      { 
        글제목.map(function(a, i){
          return (
          <div className="list">
            <h4 onClick={()=>{ setModal(true); setTitle(i); }}>{ 글제목[i] }</h4>
            <p>2월 18일 발행</p>
          </div> )
        }) 
      }
    </div>
  )
}

각각 글제목 누르면 setTitle(i) 해달라고 코드짰습니다.

map 안에서의 i가 뭐였냐면 반복문이 돌 때 마다 0, 1, 2 ... 이렇게 증가하는 정수라고 했습니다.

그래서 첫 글제목은 클릭시 setTitle(0) 이 실행될 것이고

둘째 글제목은 클릭시 setTitle(1) 이 실행될 것이고

셋째 글제목은 클릭시 setTitle(2) 이 실행될 것이고

그렇습니다. 

 

아무튼 글제목 누르면 스위치 조작이 잘되고

스위치가 조작되면 모달창 안의 글제목도 알아서 잘 바뀌는군요 성공 

 

[collapse]

 

 

 

import React, { useState } from 'react';

function App() {
  let [글제목, 글제목변경] = useState(['남자코트 추천', '강남 우동맛집', '파이썬독학']);
  let [title, setTitle] = useState(0);

  return (
    <div>
      {/* 각각의 글제목을 클릭하면 setTitle로 상태 변경 */}
      {글제목.map((글, index) => (
        <div key={index} onClick={() => setTitle(index)}>
          {글}
        </div>
      ))}
      <Modal 글제목={글제목} color="yellow" title={title} />
    </div>
  );
}

function Modal(props) {
  return (
    <div className="modal" style={{ background: props.color }}>
      <h4>{props.title === 0 ? props.글제목[0] : props.글제목[props.title]}</h4>
      <p>날짜</p>
      <p>상세내용</p>
    </div>
  );
}

이코드가 더 직관적인듯

 

Q. state를 자식컴포넌트에 만들어버리면 props 전송안해도 되지않나요?

A. 맞습니다. title같은 state도 자식컴포넌트 안에 만들어보면 편할듯요? 

하지만 지금 title이라는 state는 App도 쓰고 Modal도 쓰고 있습니다.

그렇게 다양한 컴포넌트에서 쓰이는 state는

컴포넌트들 중 최고로 높은 부모에게 만들어놔야합니다. 

 

왜냐면 state는 부모 → 자식 전송만 가능하니까 그렇습니다. 

state를 자식에 만들어놨는데 갑자기 부모가 그게 필요해지면 어떻게 할 방법이 없으니까요. 

생각하기 귀찮으면 그냥 대부분 App 컴포넌트안에 만들면 됩니다. 

 

 

 

 

오늘 요약 :

1. 그래서 UI만드는 3-step 외워주면 알아서 뭐든 만들 수 있습니다.

이제 저에게 그만 물어보고 알아서 만들도록 합시다. 

 

2. state는 state를 사용하는 컴포넌트 중 최고 부모에 만들어놓아야합니다.