내맘대로 frontend 낙서장

next13 강의 들으면서 실습하기 (2) 본문

react

next13 강의 들으면서 실습하기 (2)

deadeye 2023. 4. 17. 10:22

serverComponent와 client Component에서의 route방법

// serverComponent

import Link from "next/link"

<Link href="링크"> 이건 서버컴포넌트 링크</Link>

//client

'use client'

import {useRouter} from 'next/navigation'

export default function DetailLink(){
  let router = useRouter()
  return (
    <button onClick={()=>{ router.push('/') }}>버튼</button>
  )
}
  • router.forward() : 앞으로가기
  • router.refresh() : 새로고침 ( 이전과 바뀐부분을 분석해서 바뀐부분만 새로고침)
  • prefetch기능 : 서버, 클라이언트 둘다 사용가능
// client

<button onClick={()=>{ router.prefetch('/어쩌구') }}>버튼</button> 

//server
// 링크 페이지를 자동으로 미리 로드해줌
<Link href={'/링크'}>링크</Link>

// false도가능
// 링크 많은 게시판 같은 경우 미리 로드하면 자원 낭비임
<Link href={'링크'} prefetch={false}>링크</Link>

Next.js에서 서버기능

src/app폴더안에 api파일을 만들고 js(ts)파일을 만듬

**코딩애플 동영상 예시

 

//form에서(예시)
// 이런식으로 작성하면
export default async function Write() {
  return (
    <div className="p-20">
      <form action="/api/post/new" method="POST">
        <input name="title" placeholder="글제목"/>
        <input name="content" placeholder="글내용"/>
        <button type="submit">전송</button>
      </form>
    </div>
  )
} 

///api/post/new에서는
export default async function handler(요청, 응답) {
  if (요청.method == 'POST'){
    if (요청.body.title == '') {
      return 응답.status(500).json('제목써라')
    }
    try {
      let db = (await connectDB).db('forum')
      let result = db.collection('post').insertOne(요청.body)
      응답.redirect(302, '/list')
    } catch (error) {
      DB에러시 실행할코드~~
    }
    
  }
}

참고로 서버폴더는 fetch 로도 호출 가능

<button className="list-btn" onClick={(e) => {
  fetch('/api/post/delete', { method: 'POST', body: result[i]._id }).then(()=>{
    e.target.parentElement.style.opacity = 0;
    setTimeout(()=>{
      e.target.parentElement.style.display = 'none';
    }, 1000)
  })
}}>🗑️</button>

array, object state 변경하는 방법

// 바로 코드들어가면

[arr , setArr] = useState([데이터 어쩌구])
let copy = [...arr]
copy[0]++
setArr(copy)
  • state를 ... 문법으로 복사하고
  • state의 [0]번 항목을 +1 해주고 
  • state변경함수() 쓰면 됩니다.

왜 굳이 저렇게 귀찮게 바꿀까 간단히 생각하면 그냥 arr[0]++은안되나...?

리액트의 동작 원리는 state를 썼을때

컴퓨터는 기존 state == 신규 state를 검사하는데

같으면 state변경이 일어나지 않음

따라서 arr[0]++ , setArr(arr) 하면 기존 , 신규 같기때문에 복사하고 수정한다음 옮겨야 됨

 

더보기

React에서 상태를 업데이트할 때, 기존 배열이나 객체를 직접 수정하지 않고 항상 새로운 복사본을 생성하여 그것을 수정해야 하는 이유는 불변성(immutability)을 유지하기 위해서입니다. 

 

JavaScript에서 객체와 배열은 참조형(reference type)입니다. 

즉, 변수에 저장된 값은 객체나 배열의 메모리 주소를 가리키고 있습니다.

 

 따라서 객체나 배열을 복사할 때, 단순히 변수에 저장된 메모리 주소만 복사하는 것이 아니라, 원본 객체나 배열의 내용을 새로운 메모리 영역에 복사해야 합니다.

 React에서 상태를 업데이트할 때, 불변성을 유지해야 하는 이유는 상태가 변경될 때마다 컴포넌트가 다시 렌더링되기 때문입니다. 

 

만약 상태가 변경될 때마다 기존 객체나 배열을 직접 수정하면, React는 상태가 변경되었다는 것을 감지하지 못할 수 있습니다. 

이렇게 되면 예기치 않은 문제가 발생할 수 있습니다. 

 

예를 들어, 불변성을 유지하지 않고 배열을 수정하는 경우, 다른 컴포넌트에서 해당 배열을 참조하고 있을 때 예기치 않은 결과를 가져올 수 있습니다. 

또한, React의 성능 최적화 기능인 shouldComponentUpdate나 React.memo 등을 사용할 때도 불변성을 유지해야 합니다. 

 

이러한 이유로 React에서는 상태를 업데이트할 때 불변성을 유지하도록 권장하고 있습니다.

 


여기까지에용~~~

실제로 실습해보면서 느꼈지만 다른부분은 ㄱㅊ은데 api부분을 다루는 부분은 좀더 해봐야될거 같음 지금은 또 form으로만 실습을 해봤기 때문에 다른방식으로도 마침 지금 apollo를하고있기에... 이부분으로 진행하는것도 기회가 되면 쓰는걸로(결국 쓰겠단 소리임;;)