20230204 [react] - props

lionloopy·2023년 2월 3일
0

리액트

목록 보기
2/18

props

:컴포넌트끼리의 정보 교환 방식이다.
부모 컴포넌트가 => 자식 컴포넌트에게 물려주는 데이터
props는 반드시 위에서 아래방향으로 흐른다. (부모 => 자식)

// src/App.js

import React from "react";

function App() {
  return <GrandFather />;
}

function GrandFather() {
  return <Mother />;
}

function Mother() {
	const name = '홍부인';
  return <Child />;
}

function Child() {
  return <div>연결 성공</div>;
}

export default App;

props drilling
:부모 -> 자식 -> 그자식 -> 그 자식으로 계속 물려주는 현상
props children

import React from 'react'

function App() {
  return <User>안녕하세요!</User>
}

function User(props){
  console.log('props',props)
  return <div>{props.children}</div>
}

export default App

state

:컴포넌트 내부에서 바뀔 수 있는 값을 의미하며, UI를 바꾸기 위해서 사용한다. 따라서 변경되는 값은 반드시 state로 선언해야 한다.
(클릭을 눌렀을 때 컨텐츠가 변경되는 것, input태그 안에서 값을 입력했을 때 변경되는 것)
state기본 코드

const [ value, setValue ] = useState( 초기값 )

클릭을 눌렀을 때 컨텐츠 변경

function App() {

const [name, setName] = useState('김할아버지')

  return (
    <div>
      {name}
      <br/>
      <button onClick={function(){
        setName('박할아버지')
      }}>클릭</button>
    </div>
  )
}

:const [name, setName] 으로 useState를 만들고,
초기값으로 '김할아버지'를 넣어준다.
div안에 자바스크립트 {name}을 넣어 name의 초기값이 나오게 한다.
button에 onclick이벤트를 걸고, 거기에 함수를 넣어준다.
함수 안에 setName을 넣어 클릭하면 '박할아버지'로 바뀔 수 있도록 한다.

input태그 안에서 값 입력시 변경

function App() {

const [fruit, setFruit] = useState('')

  return (
    <div>
      과일 : <input 
      value = {fruit}
      onChange = {function(event){
        setFruit(event.target.value)
      }} />
      {fruit}
    </div>
  )
}

:const [fruit, setFruit]로 useState를 만들고, 초기값은 비워둔다.
input태그 안에 value 값을 {fruit}로 넣어주고, onChange 키에는 함수를 넣어준다.
함수에는 event가 매개변수로 항상 걸리는데 이때 event.target.value를 출력하면 input값에 입력한 값만 출력되게 된다.
onChange밑에 있는 {fruit}값에는 input에 입력한 값이 바로 나오게 된다.

응용 - 회원가입

function App() {

  const [id, setId] = useState('')
  const [pw, setPw] = useState('')

  const onIdChangeHandler = (event) => {
    setId(event.target.value)
  }

  const onPwChangeHandler = (event) => {
    setPw(event.target.value)
  }
  return (
    <div>
      아이디:<input type='text'
      value ={id}
      onChange = {onIdChangeHandler} />
      <br/>
      비밀번호:<input type='password'
      value = {pw}
      onChange = {onPwChangeHandler}/>
      <br/>
      <button onClick={()=>{
        alert(`고객님이 입력하신 아이디는 ${id}이며, 비밀번호는 ${pw}입니다.`)
        setId('')
        setPw('')
      }}>로그인</button>
    </div>
  )
}

불변성

:메모리에 있는 값을 변경할 수 없는 것
컴포넌트가 화면에 그려지기 위해서는 렌더링이 되어야 하고,
렌더링이 되기 위해서는 state가 바뀌어야 한다.
리액트에서 렌더링 할지 말지 결정하는 조건은 state가 변경되었는가?와 같다.
배열이나 객체가 나오면, 불변성을 지켜주는 map, filter, [...]등을 이용해서 원시형이 아닌 것들을 처리한다.


불변성이 지켜지지 않는다면?
리액트는 원본 객체(state)의 값이 업데이트 되는 것을 감지하지 못하게 되어 렌더링이 되지 못한다. 즉, 불변성이 지켜지지 않으면 객체 내부의 값이 새로워져도 바뀐 것을 감지하지 못하기 때문에 불변성은 중요하다.

  • 이러한 불변성을 지키기 위해 원시형은 상관이 없지만, 객체나 배열의 경우에는 map, filter, […]등으로 불변성을 지켜준다.

function App() {
  const [obj, setObj] = useState({
  	name: 'WonJang',
    age: 21,
  );

  return (
    <div>
    <div>{obj.name}</div>
      <button onClick={() => {
      		obj.name = 'twojang'
            const obj2 = {...obj}
            //2.새로운 객체를 만들고 거기에 할당해준다.
            setObj(obj2)
            //1.이렇게 해도 클릭했을 때 obj.name이 바뀌지 않음
            //주소값을 바꿔주자!
            //메모리 - 주소값 생각하기! 따라서 새로운 객체를 만들어줘야함
      }>버튼</button>
    </div>
  );
}

개념정리

컴포넌트
:리액트의 핵심 빌딩 블록/화면의 특정 부분이 어떻게 생길지 정하는 선언체
리액트에서 개발할 모든 어플리케이션은 컴포넌트라는 조각으로 구성된다.
컴포넌트는 UI구축 작업을 훨씬 쉽게 만들어준다.
UI요소를 컴포넌트 내부에서 JSX를 통해 선언하면 이를 리액트과 화면에 그려준다.

명령형 프로그래밍
:어떻게(HOW)를 중요시 여겨서 프로그램의 제어와 흐름과 같은 방법을 제시하지 않고 목표를 명시하는 형태
명령형으로 작성된 코드의 경우 'hello'를 출력하기 위해 컴퓨터가 수행하는 절차를 일일히 코드로 작성해주어야 한다.

const root = document.getElementById('root')
const header = document.createElement('h1')
const headerContent = document.createTextNode('hello')

header.appendChild(headerContent)
root.appendChilde(header)

선언형 프로그래밍(React)
:무엇(WHAT)을 중요시 여겨서 제어의 흐름보다는 원하는 목적을 중요시 여기는 형태
내가 UI를 선언하고 render함수를 호출하면 리액트가 알아서 절차를 수행해 화면을 출력해준다.

const headaer = <h1>hello</h1> //jsx
ReacDOM.render(header, document.getElementById('root'))

렌더링
:컴포넌트가 현재 props와 state의 상태에 기초하여 UI를 어떻게 구성할지 컴포넌트에게 요청하는 작업

ex)컴포넌트 = 주방장 / 리액트 = 웨이터 / UI - 제공되는 음식
1. 렌더링을 일으키는 것은(triggering) - UI를 주문하고 주방으로 전달
2. 렌더링을 한다는 것(rendering) - 주방에서 컴포넌트가 UI를 만들고 준비
3. 렌더링 결과를 실제 DOM에 커밋(commit) - 리액트가 준비된 UI를 손님 테이블에 올려놓는 것

렌더링이 발생하는 경우
1. 첫 리액트 앱을 실행했을 때
2. 현재 리액트 내부에 어떤 상태(state)에 변경이 발생했을 때

  • 컴포넌트 내부 state가 변경되었을 때
  • 컴포넌트에 새로운 props가 들어올 때
  • 상위 부모 컴포넌트에서 위의 두 이유로 렌더링일 발생했을 때

리렌더링
:첫 렌더링은 자동으로 일어나지만, 첫 렌더링이 끝난 이후에 추가로 렌더링을 트리거 하려면 상태를 변경해주면 된다.
새로운 주문(리렌더링)이 일어나면 리액트가 변경된 내용을 주방에 있는 요리사인 컴포넌트에 전달하고, 컴포넌트는 새로운 변경된 주문을 토대로 새로운 요리(UI)를 만든다.

응용 - 카운트

function App() {
  const [count, setCount] = useState(0)
  const minusCount = () => {
    setCount(count-1)
  }
  const plusCount = () => {
    setCount(count+1)
  }
  return (
    <div>
      {count} <br/>
      <button onClick={minusCount}>-</button>
      <button onClick={plusCount}>+</button>
    </div>
  )
}
profile
Developer ʕ ·ᴥ·ʔ ʕ·ᴥ· ʔ

0개의 댓글