상위 컴포넌트에서 하위 컴포넌트로 데이터를 전달하는 방법

- 하위컴포넌트의 props 객체 사용

// 상위 컴포넌트
import React from 'react';
import Hello from '.Hello'; // 자식 컴포넌트 injection

function App() {
	return (
    	<Hello nmae-"react" color="red"/> // name 이라는 props 전달
    );
}

export default App;

// 하위 컴포넌트 (함수형일 경우, props 객체 Input이 존재)

import React from 'react';

const Hello = (props) => {
	return {
      ...
      <div> {props.name}</div>
      <div style={ { color : props.color } } />
      ...
    }
}

export default Hello;

- 하위 컴포넌트는 기본적으로 props 객체(상위 컴포넌트에서 하위컴포넌트로 전달됨)를 Input으로 가지고 있다.

 

ES6 문법 중 "비구조화할당"을 통한 명료하게 작업하기

// 비구조화할당 문법 미사용시
function Hello(props) {
	return <div style={ { color : props.color } }> 이름 : {props.name} </div>
}

// 비구조화할당 문법 사용시
function Hello( { name, color } ) { // ★
	return <div style={ { color }}> 이름 : {name} </div>
}

- ES6에서는 { color : color, name: tName }를 { color, name : tName } 으로 축약해서 표현할 수 있다.

- ES6에서는 "비구조화 할당" 문법을 통해, { a: 1, b: 2, c : 3 ...} 을가지고 있는 객체를 { a, b} 로 표현할 경우, 해당 객체에서 a 속성과 b 속성을 가진 새로운 객체인 것처럼 할당해줄 수 있다.

 

Props의 기본값 설정하기 : props.defaultProps = { };

- 상위 컴포넌트에서 특정 prorps 속성에 값을 주지 않아도, 하위 컴포넌트상에서 기본값으로 수행하고 싶을 경우가 있다.

- 하위 컴포넌트 상에서 (하위컴포넌트명).defaultProps = { props 명 : "기본값" } 을 선언해줌으로, 일부 props 속성에 대한 기본값을 지정해줄 수 있다.

function Hello({ color, name }) {
	return <div style={{color}}> {name} </div>
}
Hello.defaultProps = {
	name: '이름 없음'
};

 

상위 컴포넌트 상에서, 하위컴포넌트의 태그 사이의 값에 접근하기 : props.children

- 상위 컴포넌트 상에서, <Hello> ... </Hello> 형식으로 사용되었을 경우, 태그 사이의 값은 하위 컴포넌트에서, props.children으로 접근 할수 있다.

// 상위 컴포넌트
function App() {
	return (
    	<>
        	<WrapComponent>
            	<Hello />
                <Hello />
            <WrapComponent>
        </>
    );
}

// WrapComponent

function WrapComponent({children}) {
	return (
    	<div style={{color : "red"}}>
 			{ children } // 이렇게 WrapComponent 사이의 태그를 넣어주지 않으면, <WrapComponent> 사이의 태그들은 무시된다.       
        </div>
    );
}

- 이렇게 WrapComponent 사이에 들어가는 태그를 고려하지 않으면, <WrapComponent> 사이의 태그들은 무시되고, 렌더링 되지 않는다..

 

조건부 렌더링

- 특정 조건에 따라 렌더링하거나 하지 않게 하고 싶을 때가 존재한다.

function Hello({color, name, isVisible}) { // isVisible이라는 사용자정의 props
  return (
  	<div>
    	{ isVisible ? <span>추가된 내용</span> : null } // 방법1. 삼항 연산자 사용
        { isVisible && <span>추가된 내용</span> }       // 방법2. 단축 평가 논리 계산법
    </div>
  )
}

 

Props 값 설정을 생략할경우

- 만약 상위 컴포넌트에서 하위 컴포넌트를 사용할 때, props명만 선언하고, 값을 넣지 않았을 경우, props의 값은 true로 간주한다.

<Hello name="test" color="black" isVisible /> // isVisible의 값은 true이다.

 

State를 통한 컴포넌트내 변동값 관리

- react 16.8 버전 이전의 함수형 컴포넌트의 경우, 컴포넌트 내 변수(상태값을 저장할 수 있음)를 저장할 수 없었다.

- react 16.8 버전 이후에는 Hooks라는 기능이 도입되어, 함수형 컴포넌트에서도 상태값을 관리할 수 있게 되었다.

- useState()라는 함수가 바로 React의 Hooks 중의 하나이다.

- userState()라는 Hooks 함수 없이는 함수형 react 컴포넌트 내에서 상태값 관리를 할 수 없다는 것을 의미한다.

useState() 함수란?

-> React 컴포넌트 상에서, 1회적으로 사용되는 변수가 아니라, 클래스 내 멤버변수처럼 컴포넌트 내에 상태값을 저장할 수 있는 변수가 필요한 경우 쓰이는 Hooks 함수이다.

-> const [현재 상태변수,  Setter 함수] = useState(변수 초기 상태값); 형식으로 컴포넌트 내부에 선언하여 사용한다.

-> 첫번쨰 원소는 현재 상태, 두번째 원소는 setter함수이다.

const numberState = userState(0);
const number = numberState[0];
const setNumber = numberState[1];

비구조화 할당
const [number, setNumber] = useState(0); // ★

1. number는 항상 현재상태의 변수값을 반환합니다.
2. setNumber()를 호출 시, 자연스럽게 number의 값이 변동됩니다.
   (react state는 불변성을 가져야 하므로, state값을 바꾸려면, setNumber 함수만을 통해 업데이트할 수 있습니다.)
3. useState의 매개변수로 변수의 초기 상태값을 지정할 수 있습니다.

State를 업데이트하는 2-3가지 방법

- 일반적인 값을 useState()의 set함수에 일반값을 넣을 경우, 상태값을 바꿀 수 있다.

- 만약 set함수에 함수 형태를 넣게 되면, 이전 상태값을 참고해서, 다음값을 넣어 줄 수 있다

const [num, setNum] = useState(0);

const onIncrease = () => {
    setNum(11);						// 1. 일반 값 할당
    setNum(num + 1);				// 2. 현재 상태값에 추가한 값을 할당
    setNum(prevNum => prevNum + 1); // 3. 함수형 업데이트
}

State가 될 수 있는 2-3가지 변수 종류

- 일반형 변수

- 리스트 변수

- 객체형 변수

const [number, setNumber] = useState(0);

const [list, setList] = useState([]);
// setList([...list, ...[444, 555, 666]]);

const [obj, setObj] = useState({});
// setObj({...obj, objVal: 111 });

- ES6 spread(...) 문법과 비구조화할당 문법이 매우 빈번하게 사용된다.

 

※  State 변수가 객체형일 경우

- State의 "불변성"을 지킬 수 있도록, spread 문법 등으로, 객체를 새로 복사해서 넣어주어야 한다.

- React의 동작원리상 가상돔을 real dom과 비교해서 리렌더링해야할 부분을 도출할 때, Props, State의 객체 value 비교가 아닌 Reference 비교를 수행하기 때문이다.

- obj[name] = value라고 할당해도, react는 컴포넌트를 리렌더링 시키지 않는다.

- useState() 함수가 setObj() 와 같은 setter 함수를 제공하는 이유가 여기에 있다.

- 리액트에서 State 객체를 업데이트하게 될 때에는 기존 객체를 직접 수정하면 안되고, 새로운 객체를 만들어서 먼저 새 객체에 변화를 주어야 한다.

- setObj({ ...obj, name: value}) 형태가 일반적인 모습니다.

 

useState()가 아닌 setState()를 통해서도 State를 변경할 수 있습니다.

- 권장하지 않는 방식입니다.

- setState()로 상태를 호출할 경우, 실제로 값이 변경되지 않았어도 무조건적으로 컴포넌트를 리렌더링 한다는 비효율이 발생합니다.

- setState()는 내부적으로 shouldComponentUpdate(nextProps, nextState)를 트리거하는데, 해당 메소드의 반환값에 따라 render 호출 여부가 결정됩니다. 이 메소드를 재정의하지 않으면 setState 호출 시마다 render함수가 호출되기 때문에, 최적화를 위해서는 setState를 쓰지 않거나, shoudComponentUpdate를 재정의하는 것이 필요합니다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기