🟥 훅 (Hooks)

리액트 v16.8 부터 도입된 개념으로

원래 함수형 컴포넌트에서는 state관리가 불가능했으나,

함수형 컴포넌트에서도 상태관리를 할 수 있도록 도입된 기술입니다.

 

 

useState, useEffect, useReducer, useMemo, useCallback

🔸 useState

상태를 관리하기 위한 가장 기본적인 훅 입니다.

...
const [count, setCount] = useState(0);  //useState의 인자로는 초기값을 넘겨줍니다. 

onClick = () => {
  setCount(count+1);
}
return (
  <>
    <div>{count}</div>
    <button onClick={onClick}</button>
  </>
)
...

useState의 인자로는 상태관리를 위한 초기값을 넘겨줍니다. 

그러면 배열이 반환되는데, 첫번째 인자는 현재의 상태(state)를 나타내고, 두번째 인자는(setCount)는 상태를 업데이트할 때 실행되는 함수명입니다. 

 

 

 

🔸 useEffect

컴포넌트가 실제 DOM에 렌더링된 직후마다 실행됩니다.

클래스형 컴포넌트에서 사용하는 componentDidMountcomponentDidUpdate를 합친 형태로 보아도 무방합니다.

 

  • 마운트 될 때만 실행하고 싶을 때

함수의 두 번째 파라미터로 빈 배열을 넣어주면 최초 마운트 될 때만 한 번 실행 됩니다.

useEffect( () => {
  console.log("마운트될 때만 실행됩니다.");
}, []);

 

  • 특정 값이 업데이트될 때만 실행하고 싶을 때

함수의 두 번째 파라미터로 검사하고 싶은 state값을 넣어주면 됩니다. 

아래 내용은 name의 상태가 변경될 때 마다 log를 찍는 로직입니다.

useEffect( () => {
  console.log("name");
}, [name]);

 

  • 뒷정리하기

컴포넌트가 언마운트되기 전이나 업데이트되기 직전에 어떤 작업을 필요로 하는 경우, useEffect함수 내에서 후처리를 위한 함수를 반환해 주어야 합니다.

useEffect( () => {
  console.log("effect");
  return () => {
    console.log('cleanup');
  }
}, [] ); // 오직 언마운트시에만 후처리 함수를 호출하고 싶다면 두번째 파라미터에 빈배열을 넘긴다.

 

 

 

🔸 useReducer

useReduceruseState보다 더 다양한 컴포넌트 상황에 따라 다양한 상태를 다른 값으로 업데이트하고 싶을 때 사용하는 Hook입니다.

 

카운터 구현하기

import { useReducer } from 'react';

function reducer(state, action) {
  swtich (action.type) {
    case 'INCREMENT' :
      return { value : state.value + 1 }
    case 'DECREMENT' :
      return { value : state.value - 1 }
    default :
      // 아무것도 해당되지 않으면 기존상태 반환
      return state;
  }
}

const Counter = () => {
  const [state, dispatch] = useReducer(reducer, { value: 0});
 
  return (
    <div>
      <p>
        현재 카운터 값은 <b>{state.value}</b>입니다. 
      </p>
      <button onClick={ () => dispatch({type : 'INCREMENT'})}>+1</button>
      <button onClick={ () => dispatch({type : 'DECREMENT'})}>-1</button>
  );
};

export default Counter;

useReducer에 첫 번째 파라미터로는 리듀서 함수를 넣고, 두 번째 파라미터에는 해당 리듀서의 기본값을 넣어줍니다.

이 훅을 사용하면 state 값과 dispatch 함수를 받아오는데, 여기서 state는 현재 카리키는 상태이고, dispatch는 액션을 발생시키는 함수입니다.

useReducer 사용시 가장 큰 장점은 컴포넌트 업데이트 로직을 컴포넌트 바깥으로 빼낼 수 있다는 것입니다.

 

 

 

🔸 useCallback

 성능 최적화를 위해 사용되는 훅 중 하나입니다.

useCallback을 이용하면 함수를 메모이제이션해 함수 인스턴스의 재사용이 가능합니다. 

 

함수컴포넌트 안에서 함수를 만들어 사용하면, 컴포넌트가 렌더링될 때 마다 새로 만들어진 함수 인스턴스를 사용하게 되며, 이는 성능에 악영향을 줄 수 있습니다. 

따라서 최적화가 필요한 상황에 사용합니다.

const memoizedCallback = useCallback(callbackFunction, dependencyArray);

첫 번째 파라미터로는 메모이제이션 하고자하는 함수를 전달하고, 두 번째 파라미터로는 상태 변경 모니터링이 필요한 stateprops를 전달합니다. 

 

import React, { useState, useCallback } from 'react';

function Counter() {

  const [ count, setCount ] = useState(0);

  const handleClick = useCallback( () => {
    setCount(count+1);
  }, [count]);

  return (
   <div>
     <p>Counter: {count}</p>
     <button onClick={handleClick} />
   </div>
  );
}

count가 변경되지 않는 한, 같은 함수 인스턴스가 재사용되어 불필요한 리렌더링을 방지할 수 있습니다. 

 

 

 

🔸 useMemo

useCallback과 같이 성능 최적화를 위해 사용되는 훅 중 하나입니다. 

useCallback이 컴포넌트의 함수 인스턴스를 재 사용하기 위해 사용한다면, useMemo는 연산 비용이 높은 계산 결과를 메모이제이션하기 위해 사용합니다. 

const memoizedValue = useMemo(() => computeValue, dependecyArray);

 

useMemo는 값을 캐시하므로, 이전 계산 결과를 재사용해 성능을 향상시킬 수 있습니다.

import React, { useState, useMemo } from 'react';

function ExpensiveComponent({data}) {
  const expensiveResult = useMemo(() => {
    // data 배열 요소들을 모두 합산하는 연산 (고비용)
    return data.reduce((sum, num) => sum+num, 0);
  }, [data] );

  return <div>Expensive Result: {expensiveResult}</div>;
}

 

위의 예시에서 data 배열이 변경될 때 마다 expensiveResult를 다시 계산합니다. 

그렇지 않으면, 캐시된 결과를 사용해 비용을 아끼고 성능을 향상시킵니다. 

 

data가 변경되지 않는 한, 이전 결과를 그대로 사용하기 때문에 중복된 계산을 피할 수 있습니다. 

🟥 컴포넌트의 라이프 사이클

 

모든 리액트 컴포넌트는 라이프사이클을 가지고 있습니다.

 

리액트 컴포넌트는 버튼 하나로 표현될 수도 있고, 페이지 전체로 표현될 수도 있다고 했죠.

컴포넌트는 "UI조각"이기 때문에 실제 DOM에 나타나기도 하고(생성), DOM에서 사라지기도 합니다.(소멸)

즉, 컴포넌트의 생성부터 소멸까지를 라이프 사이클이라고 합니다.

컴포넌트의 라이프사이클

 

라이프 사이클은 마운트, 업데이트, 언마운트 총 세가지 카테고리로 나뉩니다.

 

[마운트]

실제 DOM이 생성되서 화면에 그려지는 것을 마운트라고 합니다.

호출 순서는 다음과 같습니다.

  1. Constructor - 컴포넌트를 새로 만들때마다 호출되는 클래스 생성자 메서드입니다.
  2. render - UI를 렌더링하는 메서드 입니다.
  3. componentDidMount - 브라우저에 실제 DOM 이 그려진 후에 호출되는 메서드입니다.

 

[업데이트]

컴포넌트는 아래와 같이 총 네 가지 경우에 업데이트 합니다.

  1. state가 바뀔 때
  2. props가 바뀔 때
  3. 부모 컴포넌트가 리렌더링될 때
  4. this.forceUpdate로 강제로 렌더링을 발생시킬 때

그리고 업데이트 작업이 끝나면, componentDidUpdate 메서드가 실행됩니다.

 

[언마운트]

마운트의 반대 과정. 즉 컴포넌트가 DOM에서 사라지기 전에 호출하는 메서드입니다.

componentWillUnmount

 

 

 

🟥 라이프사이클 메서드

라이프 사이클에서 사용 가능한 메서드들이 있습니다.

 

Will접두사가 붙은 메서드는 어떤 작업을 작동하기 전에 실행되고,

Did접두사가 붙은 메서드는 어떤 작업을 작동한 후에 실행됩니다.

 

❗ 라이프 사이클 메서드는 클래스형 컴포넌트에서만 사용할 수 있고,
 함수형 컴포넌트에서는 Hooks 를 사용해 비슷한 작업을 처리할 수 있습니다.

 

🔶 return 메서드

리액트 요소를 반환하며, 화면을 그리는 역할을 담당합니다.

해당 메서드 안에서 propsstate에 접근할 수 있습니다.

아무것도 보이고 싶지 않다면 null이나 false를 리턴한면 됩니다.

주의사항으로는, 이벤트 설정이 아닌 곳에서 setState를 사용하면 안되며, 브라우저 DOM에 접근해서도 안됩니다. DOM정보를 가져오거나 state에변화를줄 때는 componentDidMount에서 처리해야 합니다.

 

 

🔶 constructor 메서드

컴포넌트의 생성자 메서드로 컴포넌트를 만들 때 처음으로 실행됩니다.

 

 

🔶 static getDerivedStateFromProps 메서드 

props로 받아온 값을 state에 동기화시키는 용도로 사용하며, 컴포넌트가 마운트 될 때와 업데이트 될 때 호출됩니다.

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.value !== prevState.value) { //조건에 따라 특정값 동기화
    return { value : nextProps.value };
  }
  return null; // state를 변경할 필요가 없다면 null을 반환
}

 

🔶 componentDidMount 메서드

컴포넌트를 만들고, 첫 렌더링을 다 마친 후 실행합니다.

이 안에서 다른 자바스크립트 라이브러리 또는 프레임워크의 함수를 호출하거나 이벤트 바인딩, setTimout, setInterval, 네트워크 요청 같은 비동기 작업을 처리하면 됩니다.

 

 

🔶 shouldComponentUpdate 메서드

이것은 props또는 state를 변경했을 때, 리렌더링을 시작할지 여부를 지정하는 메서드입니다.

이 메서드에서는 반드시true값 또는 false값을 반환해야 합니다.

 

컴포넌트를 만들때 이 메서드를 따로 생성하지 않으면 기본적으로 항상 true를 반환합니다.

이 메서드 안에서 현재 propsstatethis.propsthis.state로 접근하고, 새로 설정될 props또는 statenextPropsnextState로 접근할 수 있습니다.

 

 

 

🔶 getSnapshotBeforeUpdate 메서드

getSnapshotBeforeUpdate(prevProps, prevState) {..}

render 메서드에서 만들어진 결과물이 브라우저에 실제 반영되기 직전에 호출됩니다.

이 메서드에서 반환하는 값은 componentDidUpdate 에서 세 번째 파라미터인 snapshot 값으로 전달받을수 있는데요, 주로 업데이트 하기 직전의 값을 참고할 일이 있을때 사용됩니다.(예: 스크롤 위치 유지 등)

 

 

 

🔶 componentDidUpdate메서드

componentDidupdate(prevProps, prevState, snapshot) {..}

리렌더링을 완료한 이후 실행합니다.

prevProps, prevState를 사용해 컴포넌트가 이전에 가졌던 데이터에 접근할 수 있습니다.

세번째 파라미터인 snapshot에는 getSnapshotBeforeUpdate 의 리턴정보가 들어있습니다.

 

 

 

🔶 componentWillUnmount 메서드

컴포넌트를 DOM에서 제거할 때 실행합니다.

componentDidMount에서 등록한 이벤트, 타이머, 직접 생성한 DOM이 있으면 여기서 제거 작업을 해야합니다.

 

 

 

🔶 componentDidCatch 메서드

컴포넌트 렌더링 도중에 에러 발생시 어플리케이션이 먹통되지 않고, 오류 UI를 보여줄 수 있게 해줍니다.

componentDidCatch(error, info) {
  this.setState({
    error : true
  });
  console.log({error, info});  //console.log대신 서버 API를 호출해 로그 수집도 가능합니다.
}

error는 파라미터에 어떤 에러가 발생헀는지 알려주며, info는 어디에 있는 코드에서 오류가 발생했는지에 대한 정보를 줍니다.

그러나 컴포넌트 자기 자신의 에러는 잡아낼 수 없고, 자식 컴포넌트에서 발생하는 에러를 잡아낼 수 있습니다.

 

 

 

출처 및 참고자료

김민준님 저 - 리액트를 다루는 기술

🟥 Props

 

properties를 줄인 표현으로 컴포넌트의 속성을 설정할 때 사용합니다.

props값은 해당 컴포넌트를 불러와 사용하는 부모 컴포넌트에서 설정할 수 있습니다.

컴포넌트의 필수 props를 지정하거나 props의 타입(type)을 지정할 때는 propTypes를 사용합니다.

 

App.js

...
  return <MyComponent name="리액트" age={10}/>;
...

 

MyComponent.js

import PropTypes from 'prop-types';  // PropTypes 사용을 위해 추가

const MyComponent = {name, age}=> {
  return <div> 안녕하세요, 제 이름은 {name}입니다. 제 나이는 {age}입니다.</div>;
};

// defaultProps 설정 방법
MyComponent.defaultProps = {
  name : '지상렬'
};

// PropTypes지정 방법
MyComponent.propTypes = {
  name : PropTypes.string
  age : PropTypes.number.isRequired  // 필수 값 isRequired
};

export default MyComponent;

 

defaultProps와 propTypes 지정은 필수는 아니지만, 대규모 어플리케이션 개발 프로젝트 진행시 또는 협업시 개발 능률 향상을 위해 사용을 권장합니다.

 

 

🟥State

컴포넌트 내부에서 바뀔 수 있는 값을 의미합니다.

props는 컴포넌트가 사용되는 과정에서 부모 컴포넌트가 설정하는 값이며,

컴포넌트 자신은 해당 props를 읽기전용으로만 사용할 수 있습니다.

 

props를 바꾸려면 부모 컴포넌트에서 바꾸어 주어야 합니다.

❗ props를 사용한다고 해서 값이 무조건 고정되는건 아닙니다.
부모 컴포넌트의 state를 자식 컴포넌트의 props로 전달하고,
자식 컴포넌트에서 특정 이벤트가 발생했을 때 부모 컴포넌트의 메서드를 호출하면 props도 유동적으로 사용할수 있습니다.

 

 

클래스형 컴포넌트에서 state 초깃값은 객체 형태로 넣어주어야 합니다.

🔶 setState

this.setState를 사용할 때는 함수를 인자로 넣을수도 있습니다.

형식은 다음과 같습니다

this.setState((prevState, props) => {
  return {
    // 업데이트 하고싶은 내용
  }
});

prevState는 기존 상태이고, props는 현재 지니고 있는 props를 가리킵니다.

만약 업데이트 과정에서 props가 필요하지 않다면, 생략 가능합니다.

 

class Counter extends Component {
	state = {
	  number: 0;
	}
	
	return() {
	  ...
	  <button onClick={() => {
	    this.setState(prevState => {
	      return {
	        number : prevState.number+1
	      };
	    });
	    // 위 코드와 아래 코드는 완전히 똑같은 기능을 합니다. 
	    // 아래 코드는 함수에서 바로 객체를 반환한다는 의미입니다.
	    this.setState(prevState => ({
	      number: prevState.number+1
	    }));
	  ... 
	  }
	}
}

 

onClick에서 두번째로 this.setState함수를 사용할 때는 화살표 함수에서 바로 객체를 반환하도록 했기 때문에 prevState ⇒ ({ }) 와 같은 형태로 코드가 이루어집니다.

 

this.setState의 두 번째 파라미터로는 콜백함수를 등록해 작업을 처리할 수 있습니다.

 

 

클래스형 컴포넌트에서 setState를 사용하며, 함수형 컴포넌트에서는 Hook중 하나인 useState를 사용합니다. 

 

🔶 useState

useState 함수의 인자에는 상태의 초깃값을 넣어 줍니다.

클래스형 컴포넌트는 초깃값을 무조건 객체 형태로 넣어주어야 하지만,

함수형 컴포넌트의 초기값의 형태가 자유롭습니다.

 

함수를 호출하면 배열이 반환되는데, 첫 번째 원소는 현재의 상태이고, 두 번째 원소는 상태를 변경해주는 함수입니다.

이 함수를 세터(Setter)라 부릅니다.

 

그리고 배열 구조분해 할당을 통해 자유롭게 네이밍이 가능합니다.

아래는 avengers와 setAvengers로 네이밍 한 예입니다.

let [avengers, setAvengers] = useState(["Spider", "Hulk", "Thor"]);

return() {
  ...
  <button onClick={() => {
    // state 안바뀜
    avengers[0] = "Ironman";
    setAvengers(avengers);  	    // state 안바뀜

    let copy = avengers;
    copy[0] = "Ironman";
    setAvengers(copy);            // 마찬가지로 state 안바뀜

    let copy = [...avengers];
    copy[0] = "Spiderman";
    setAvengers(copy);            // avengers = ["Spiderman", "Hulk", "Thor"]
  }}>
  버튼
  </button>
  ... 
}

state 변경 함수는 setAvengers는 ( ) 소괄호 안에 넣은걸로 기존 state를 갈아치웁니다.

 

🔶 state 사용시 주의사항

state값을 바꾸어야 할 때는 setState 혹은 useState를 통해 전달받은 세터함수를 사용해야 합니다.

 

❗배열이나 객체의 state 변경

state가 array나 object면 독립적 카피본을 만들어서 수정해야 합니다.

array도 결국 object입니다.

백날 데이터를 변경해봤자, 변수에 저장되어있는 객체를 가리키는 주소값은 달라지지 않기 때문입니다.

 

 

배열은 배열의 내장함수를 활용하는 방법도 있습니다.

const object = { a:1, b:2, c:3 };
const nextObject = {...object, b: 4}; // 사본을 만들어서 b값만 덮어쓰기


const array = [
  { id:1, value: true },
  { id:2, value: true },
  { id:3, value: false}
];

let nextArray = array.concat({ id: 4}); // 새항목 추가
nextArray.filter(item => item.id !== 2) // id가 2인 항목 제거
nextARray.map(item => item.id === 1 ? {...item, value: false} : item); //id가 1인 항목의 value를 false로 설정

🟥 리액트는 무엇이고, 왜 사용할까 ?

리액트는 자바스크립트로 UI 개발을 하기위한 라이브러리입니다.

 

❓ 전통적인 웹 개발에서의 JavaScript
전통적인 자바스크립트는 웹 페이지에서 동적인 처리만을 담당했습니다.

웹 화면은 HTML과 CSS로 표현되고 화면 내에서 동적인 처리가 필요한 경우에 자바스크립트를 사용했습니다.
딱딱 역할 분담이 잘 되어있었는데, 왜 굳이 자바스크립트로 UI 개발을 하려는 것일까요?

 

웹 어플리케이션의 규모가 점점 더 커짐에 따라, 그만큼 어플리케이션 자체의 용량도 많이 늘어나게 되었고, 이로인해 속도는 갈수록 느려지기 시작했습니다.

 

보다 interactive하게 동적으로 동작하는 웹 사이트를 만들기 위해서 DOM(Doucment object Mode) 제어는 필요합니다.

하지만, 문제는 DOM 조작 API를 너무 자주 호출하는 것은 성능에 악영향을 준다는 것입니다.

 

CSS 계산, 레이아웃 잡기, 화면 리렌더링의 비용이 많이 발생하므로, 속도성능문제가 발생하는데 이를 리액트팀이 VirtualDOM 으로 해결했습니다.

VirtualDOM은 메모리상에 있는 DOM의 복사본인 '자바스크립트 객체'로, 화면 전환이 발생하면 as-is와 to-be 버전의 VirtualDOM을 비교하여 변경된 부분만 최소한의 DOM 조작을 통해 실제 UI에 적용합니다.

 

 

 

🟥컴포넌트 

리액트 앱은 컴포넌트로 만들어 집니다.

 

컴포넌트는 로직을 가지는 일종의 UI의 조각을 의미합니다.

컴포넌트는 버튼 하나로 표현될 수도있고, 페이지 전체로 표현될 수도있으며 재사용이 가능합니다.

 

 

컴포넌트는 마크업(Mark Up)을 반환하는 "자바스크립트 함수"입니다.

 

선언한 컴포넌트를 사용할 때는 항상 대문자를 사용해야 합니다. <MyButton />

export default 키워드는 파일에서 메인 컴포넌트에 지정합니다.

 

마크업 문법은 JSX를 사용합니다. optional이지만, 대부분의 리액트 프로젝트에서 사용하며 편리합니다.

 

ReactDOM.render를 이용해 리액트 컴포넌트를 실제 DOM에 렌더링합니다.

ReactDom은 react-dom 모듈을 불러와 사용할 수 있습니다.

리액트 버전 v17 이후부터는

React.createElement 를 사용해 리액트 컴포넌트를 실제 DOM에 렌더링합니다.

 

컴포넌트는 함수형 컴포넌트클래스형 컴프넌트 두 가지로 나뉩니다.

 

🔸 클래스형 컴포넌트

import { Component } from 'react';

class App extends Component {
  render() {
    const name="리액트";
    return <div className="react">{name}</div>;
  }
}

export default App;

클래스형 컴포넌트의 경우 state 기능 및 라이프 사이클 관리 기능을 사용할 수 있다는 것과 임의 메서드를 정의할 수 있다는 장점이 있습니다.

또 클래스형 컴포넌트는 "render함수가 꼭 있어야 하고", 그 안에서 보여 주어야 할 JSX를 반환해야합니다.

 

🔸 함수형 컴포넌트

function App() {  // 화살표 함수도 가능
  const name = "리액트";
  return <div className="react">{name}</div>;
}

export default App;

함수형 컴포넌트의 장점은 우선 클래스형 컴포넌트보다 선언하기가 훨씬 편합니다.

큰 차이는 없지만, 메모리 자원도 클래스형보다 덜 사용하고요.

 

단점은 state라이프사이클 API 사용이 불가능하다는 점인데,

이 단점은 리액트 v16.8 업데이트 이후 Hooks라는 기능이 도입되면서 해결되었습니다.

 

return 문에서는 리액트 엘리먼트를 반환해야 합니다.

공식문서에서는 함수형 컴포넌트Hooks를 사용하도록 권장하고 있습니다.

 

 

 

🟥 JSX

JavaScript 확장 문법으로 얼핏보면 HTML 같지만 실제로는 JavaScript입니다.

JavaScript정식문법은 아니며, Babel을 통해 JSX가 Javscript로 변환됩니다.

 

JSX는 HTML보다 엄격합니다.

태그는 무조건 닫아야하고(예. <br />), 꼭 하나의 최상의 태그로 감싼후 반환해야 합니다.

<div>...</div> 를 사용하거나 프래그먼트(<>...</>)를 사용합니다.

(이유는 리액트가 컴포넌트의 변화를 효율적으로 감지하려면 DOM Tree구조가 유지되어야 한다는 규칙이 있기 때문입니다.)

 

JSX를 사용하는 파일의 상단에는 항상 React import가 필요합니다.

import React from “react”;

 

❗리액트 17 버전 이후부터 package.json에서 바벨 프리셋 설정을 아래와 같이 진행하면 위에 import 구문은 생략 가능합니다. 

//"runtime" :"automatic"을 설정.
//리액트 컴포넌트마다 최상단에 react import구문 생략가능 
...
"babel": { 
  "presets": [ 
     [ "@babel/preset-react", 
       { "runtime": "automatic" } 
     ]
   ] 
 }
 ...

 

JSX 내부에 자바스크립트 표현식을 쓸 수 있습니다.

중괄호 { } 로 감싸면 됩니다.

 

JSX 에서 style 과 CSS class는 className으로 설정합니다.

인라인 스타일은 객체 형태로 작성 & camelCase 형태로 네이밍합니다.

 

예시 )

export default function Profile() {
  return (
    <>
      <h1>{user.name}</h1>
      <img
        className="avatar"
        src={user.imageUrl}
        alt={'Photo of ' + user.name}
        style={{
          width: user.imageSize,
          height: user.imageSize
        }}
      />
    </>
  );
}

스타일이 자바스크립트 변수에 의존하는 경우 style속성을 사용할 수 있습니다.

위 JSX에문에서 style속성 지정시에는 {{}} 중괄호가 두겹으로 되어있는데,

스타일 속성은 객체{ } 형태로 지정하며 JSX의 중괄호{ } 문법으로 지정한 것입니다.

 

 

🔸 JSX의 조건부 렌더링

  1. if문은 JSX안에서는 동작이 안되고, return 문 밖에서 사용 가능합니다.
  2. .JSX안에서는 3항 연산자나 && 연산자를 활용한 조건부 렌더링이 가능합니다.

 

AND 연산자(&&)를 사용한 조건부 렌더링

return (<div> { name === '리액트' && <h1>리액트입니다.</h1>}</div>);

 

❗ 주의사항으로 falsy한 값인 0은 화면에 노출됩니다.

const number = 0;
return (<div> { number && <h1>숫자입니다.</h1>}</div>); // 0 노출

 

 

🔸 리스트 렌더링

for 루프 및 arraymap()함수를 이용해 구성요소를 순회할 수 있습니다.

리스트를 순회해서 <li>와 같은 요소를 생성하는 경우 key속성을 필수로 지정해야 합니다.

 

이유는 가상돔이 변경 점을 찾는 시간을 단축시키기 위함입니다.

key속성의 값은 유니크한 숫자나 문자열로 지정해야 합니다.

...
return (
    <ul>
      {userList.map((user) => (
        <li style={{ listStyle: 'none' }} key={user.id}>
          {user.name}
        </li>
      ))}
    </ul>
  )
  ...

 

🔸 JSX내부의 주석

{/* 이런 형태로 */}

열리는 태그 내부에서는 // 이런 형태로도 가능

 

 

-참고 및 출처

김정환님 인프런 리액트 강의

김민준님 리액트를 다루는 기술

+ Recent posts