React

[React] 간단한 맛집 추천 블로그 - 2

sejin2 2024. 3. 21. 17:51

동적 UI를 만드는 방법 (모달 창 만들기)

- 유저가 조작 시 형태가 바뀌는 모달 창, 탭, 서브메뉴
1. HTML, CSS로 미리 디자인
컴포넌트로 모달 생성

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

2. UI의 현재 상태를 state로 저장

true이면 보이고, false이면 안보임

3. state에 따라 UI가 어떻게 보일지 조건문 등으로 작성

제목을 클릭하면 모달 창이 뜨도록 해준다.
처음에 false (안보임) 으로 설정된 modal창을 setModal로 true로 상태를 변경해주어 모달 창이 나오도록 한다.
한번 누르면 창이 보이고, 다시 누르면 창이 닫히도록 해야 한다.
true → false → true → false

이렇게 바꿔주면 됨 !

-> 현재 모달 창에 제목, 날짜, 상세내용은 정해진 값이 들어가는데 내가 누른 값이 들어갈 수 있도록 해주어야 한다.

더보기

리액트에서 JSX 문법에서는 반복문을 일반적인 방식으로 사용할 수 없습니다.
JSX는 JavaScript의 확장 문법이며, JavaScript 코드를 표현하는 것이므로 반복문을 사용할 수 있습니다.
하지만 JSX 내에서는 JavaScript 코드를 중괄호 {}로 감싸서 표현해야 합니다.
예를 들어, 배열의 각 요소를 매핑하여 JSX로 변환하는 경우 map() 함수를 사용할 수 있습니다.
이렇게 하면 배열의 각 요소에 대해 JSX를 반환할 수 있습니다.

// map ( ) 함수
    let arr = [3,6,8];
    arr.map(()=> {
      console.log(1);
    })

forEach랑 비슷.. ? -> arr의 개수만큼 돌면서 1을 찍는다.

[3,6,8].map((a)=> {
      console.log(a);
    });

이렇게 해도 됨 !
매개변수를 넣어주면, 매개변수에 값이 하나씩 들어온다.

let newArr = [2,7,9].map(()=> {
  return '123678';
})

매개변수가 없기 때문에 3번 돌면서, return 값이 3번 들어간 것이 newArr에 들어간다.

let newArr2 = [2,7,9].map((b)=> {
  return b*2;
}) 
console.log(newArr2);

 {
    title.map(()=> { 
      return(
        <div className="list">
          <h4>{title[1]}</h4>
          <p>2월 28일 <span className="span-left">🐷</span></p>
      </div>  
      ) 
    })
  }

title 배열에 들어있는 값을 차례대로 넣어서 반복문을 돌리고 싶다 ! 

  {
    title.map((a)=> { 
      return(
        <div className="list">
          <h4>{a}</h4>
          <p>2월 28일 <span className="span-left">🐷</span></p>
      </div>  
      ) 
    })
  }

i ( 인덱스 ) 사용 가능

{
  title.map((a, i)=> { 
    return(
      <div className="list">
        <h4 onClick={() => {setModal(!modal)}}>{a}</h4>
        <p>2월 28일 <span onClick={() => {setLike(like+1)}} className="span-left">🐷</span>{like}</p>
    </div>  
    ) 
  })
}

이렇게 하면 오류가 난다...

-> key를 넣어달라는 리액트의 법칙? 때문이다..

key를 넣어주면 warning이 뜨지 않는다.

return 바깥에서는 for문 사용 가능하 !

// map대신 for문으로 한다면
{
  function App() {
    let arr = [];
    for (let i=0; i<3; i++) {
      arr.push(<div>안녕</div>)
    }
    return (
      <div>
        {arr}
      </div>
    )
  }
}

⇒ 현재 문제점 : 돼지를 클릭하면 모든 돼지들의 숫자가 올라간다.

? state값에 하나가 들어있기 때문이다.

—> state를 각각 사용하도록 해준다. ⇒ 배열로 만들어 주면 된다.

이 또한 원본 변경이 아니라 copy해서 만들어준다.

 <p>2월 28일 <span 
    onClick={() => { 
    let copy = [...like];
    copy[i] = copy[i]+1;    // [0,0,0]  -> 해당 i값 증가 [0,2,0]
    setLike(copy)           // 배열 자체를 넘겨줌
}}

 

props

: 부모 → 자식에게 state를 전송 ( 부모 - 자식 관계일 때만 ! )

1. <자식 컴포넌트 변수이름 = {state이름}>

2. 자식 컴포넌트에서 파라미터 하나 추가하여 받는다.

→ 컴포넌트 속성을 설정할 때 사용하는 요소,
     props값은 해당 컴포넌트를 불러와 사용하는 부모 컨포넌트에서 설정할 수 있다.

버튼을 클릭하면 첫 번째 글 제목을 '김밥천국'으로 바꾸기

기존 변수와 변경하고자 하는 값 두 개를 넣어준다.

해당 제목을 눌렀을 때 모달 창이 뜨면서 클릭한 제목이 들어가야 한다.

→ 모달 창을 위한 useState 필요

function Modal(props) {
  return (
    //<div className='modal' style={{backgroundColor : props.color}}>
       <div className='modal'>
        <h4>{props.title[0]}</h4>
        <p>날짜</p>
        <p>상세내용</p>
        <button onClick={()=> {
            let copy = [...props.title];
            copy[0] = '김밥천국';
            props.setTitle(copy)
          }}>첫번째 제목 수정</button>
      </div>
  )
}

현재는 고정되어 있다.

└ 현재 어느 것을 클릭해도 0번이 나오도록 되어 있음

맛집 추천 리스트 추가
⇒ 배열에 값 하나 더 추가 ( 맵은 개수 만큼 돌기 때문에 건드릴 필요 없음 )

사용자가 input에 넣은 값을 inputValue에 넣어주고,

버튼을 클릭하면 기존 배열의 맨 앞에 inputValue값(사용자가 넣은 값)을 넣어준다.
⇒unshift 메서드 사용 : 배열의 맨 앞에 요소를 추가

<input onChange={(e)=> { setInputValue(e.target.value); }} />
 
<button onClick={()=>{
    let copy = [...title];
    copy.unshift(inputValue);
    setTitle(copy); 
}}>글추가</button>

 

삭제 버튼 만들어 클릭하면 삭제하기
⇒ splice 메서드 사용 : 배열에서 특정 위치에 있는 요소를 삭제
splice() 메서드는 배열에서 특정 위치에 있는 요소를 삭제하는 데 사용, i번째 인덱스에 해당하는 요소를 1개 삭제

<button 
			onClick={()=>{
      let copy = [...title];
      copy.splice(i, 1);
      setTitle(copy);
      }}>
삭제</button>

 

'React' 카테고리의 다른 글

[React] axios  (0) 2024.03.22
[React] 리액트 부트스트랩 적용  (0) 2024.03.21
[React] 간단한 맛집 추천 블로그 - 1  (0) 2024.03.21
[React] Component , 구조 분해 할당  (0) 2024.03.21
[React] JSX  (0) 2024.03.21