function Parent() {
return (
<div class="parent">
<h1>parent</h1>
<Child text={"child"}/>
</div>
);
};
function Child(props) {
return (
<div className="child">
<p>{props.text}</p>
</div>
);
};
Props는 객체 형태이기 때문에 props.
를 통해 접근하는데 이를 비구조화 할당(구조 분해)
문법을 사용하면 코드를 더 간결하게 작성 할 수 있다.
function Parent() {
return (
<div class="parent">
<h1>parent</h1>
<Child text={"child"}/>
</div>
);
};
function Child({text}) { // 구조 분해 문법
return (
<div className="child">
<p>{text}</p>
</div>
);
};
컴포넌트에 props를 지정하지 않았을 때 기본값을 설정하고 싶다면 defaultProps
값을 설정하면 된다.
fcuntion Hello({name}) {
return <div>{name}</div> //이름을 적어주세요
}
Hello.defaultProps = {
name : '이름을 적어주세요'
}
컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 땐, props.chidren
을 조회하면 된다.
function Parent() {
return (
<div class="parent">
<h1>parent</h1>
<Child>자식 컴포넌트 입니다.</Child>
</div>
);
};
function Child(props) {
return (
<div className="child">
<p>{props.children}</p> //자식 컴포넌트 입니다.
</div>
);
};
조건부 렌더링이란, 특정 조건에 따라 결과물을 렌더링 하는 것을 의미한다.
예를 들어 Hello 컴포넌트에서 App.js에서 전달하는 isSpecial
값이 true
이냐 false이
냐에 따라서 컴포넌트의 좌측에 * 표시를 준다면 삼항연산자를 사용할 수도 있지만, 단순히 특정 조건이 true면 보여주고 그렇지 않다면 아무 변화가 없어도 될 때는 단축 평가 논리 계산법의 &&
연산자를 사용해서 처리하는 것도 좋은 방법이다.
App.js
function App() {
return (
<Wrapper>
<Hello name="react" color="red" isSpecial={true}/>
<Hello color="pink" />
</Wrapper>
)
}
Hello.js ====> 삼항연산자 사용
function Hello({ color, name, isSpecial }) {
return (
<div style={{ color }}>
{ isSpecial ? <b>*</b> : null }
안녕하세요 {name}
</div>
);
}
Hello.defaultProps = {
name: '이름없음'
}
Hello.js =====> && 연산자 사용
function Hello({ color, name, isSpecial }) {
return (
<div style={{ color }}>
{ isSpecial && <b>*</b> }
안녕하세요 {name}
</div>
);
}
Hello.defaultProps = {
name: '이름없음'
}
props 값을 설정하게 될 때 만약 props 이름만 작성하고 값 설정을 생략한다면, 이를 true
로 설정한 것으로 간주합니다.
function App() {
return (
<Wrapper>
<Hello name="react" color="red" isSpecial />
<Hello color="pink"/>
</Wrapper>
);
}
isSpecial 이름 넣어주면 isSpecial={true}와 동일
리액트 16.8 이전 버전에서는 함수형 컴포넌트에서는 상태를 관리할 수 없었지만, 리액트 16.8 에서 Hooks 라는 기능이 도입되면서 함수형 컴포넌트에서도 상태를 관리할 수 있게 되었다. useState 라는 함수가 바로 리액트의 Hooks 중 하나다.
버튼을 누르면 숫자가 바뀌는 counter 컴포넌트를 만든 예로 useState
에 대해 알아보자 !
onIncrease
와 onDecrease
의 이벤트가 이해가 잘 안되면 리액트 핸들링 포스트다시 보기
////////////////////////////////// Counter.js
mport React, { useState } from 'react';
function Counter() {
const [number, setNumber] = useState(0);
const onIncrease = () => {
setNumber(number + 1);
}
const onDecrease = () => {
setNumber(number - 1);
}
return (
<div>
<h1>{number}</h1>
<button onClick={onIncrease}>+1</button>
<button onClick={onDecrease}>-1</button>
</div>
);
}
export default Counter;
//////////////////////////////////// /App.js
import React from 'react';
import Counter from './Counter';
function App() {
return (
<Counter />
);
}
export default App;
위의 코드에서 number
와 같이 동적인 값을 상태(state)라고 부르는데, 리액트의 useState
라는 함수를 사용하면 컴포넌트에서 상태를 관리할 수 있다.
꼭 ! 아래 코드와 같이 리액트 패키지에서 useState 라는 함수를 불러와야지 사용 가능하다.
import React, { useState } from 'react';
const [number, setNumber] = useState(0);
useState를 사용할 때는 상태의 기본값을 파라미터로 넣어서 호출하며 현재 기본값은 0이다. 그리고 이 함수를 호출하면 배열이 반환되는데 첫번째 원소는 현재 상태, 두번째 원소는 Setter 함수이다.
원래는 아래와 같은 코드이지만, 배열 비구조화 할당을 통해 각 원소를 추출한 것이다.
const numberState = useState(0);
const number = numberState[0];
const setNumber = numberState[1];
여기서 const를 사용하는 이유는? React는 상태를 변경했을 때 리렌더링 되는데 배열의 경우 주소값을 공유하면 변하지 않은 값으로 인식하기 때문에, const를 사용해서 동일한 범위 내에서 같은 참조 값을 재할당하지 않도록 보호해야 한다.