:리액트 컴포넌트를 만들 땐, 함수형과 클래스형이 있고 주로 함수형을 사용한다.
리액트 컴포넌트를 만들 땐, import를 통하여 리액트를 불러와주어야 하고,
export를 통하여 다른 컴포넌트에서 불러와 사용할 수 있다.
자식은 export로 내보내고, 부모는 import로 자식을 품는다.
자식
import React from 'react';
function Hello() {
return <div>안녕하세요</div>
}
export default Hello;
부모
import React from 'react';
import Hello from './Hello';
function App() {
return (
<div>
<Hello />
</div>
);
}
export default App;
export로 Hello를 내보내고, import로 Hello를 가져온다.
:리액트에서 생김새를 정의할 때 사용하는 문법이다.
return 아래 작성한다.
규칙
<Hello />
return(
<div>
<Hello />
<div>안녕히계세요</div>
</div>
)
<>
<Hello />
<div>{name}</div>
</>
:프로퍼티의 줄임말. 우리가 어떠한 값을 컴포넌트에 전달해 주어야 할 때 사용한다. prop는 파라미터를 통해 전달되며, 객체 형태로 전달된다.
(파라미터 : 함수 매개변수)
(부모가 자식한테 props를 통해 전달한다.)
name의 값을 조회하고 싶다면 props.name 형태로 사용하면 된다.
App컴포넌트에서 Hello컴포넌트를 사용하면서, name이라는 값을 전달해주고 싶을 때 ▼
App.js
import React from 'react';
import Hello from './Hello';
function App() {
return (
<Hello name="react" />
);
}
export default App;
Hello.js
import React from 'react';
function Hello(props) {
return <div>안녕하세요 {props.name}</div>
}
export default Hello;
export로 Hello를 내보낸 자식, import로 Hello를 받은 부모가 있다.
부모에서 자식으로 name이라는 값을 전달하고 싶을 때,
자식은 props를 파라미터로 받고 props.name으로 찍어줄 수 있다.
props는 객체형태로 전달되기 때문에 props.name으로 찍어준다.
이렇게도 바꿀 수 있다.
import React from 'react';
function Hello(name) {
return <div>안녕하세요 {name}</div>
}
export default Hello;
:컴포넌트 태그 사이에 넣은 값을 조회하고 싶을 때 활용할 수 있다.
Wrapper.js로 감싸고 싶을 때 ▼
Wrapper.js => 자식
import React from 'react';
function Wrapper() {
const style = {
border: '2px solid black',
padding: '16px',
};
return (
<div style={style}>
</div>
)
}
export default Wrapper;
App.js => 부모
import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';
function App() {
return (
<Wrapper>
<Hello name="react" color="red"/>
<Hello color="pink"/>
</Wrapper>
);
}
export default App;
Wrapper를 받아와 원래 있던 내용을 감쌌지만, 화면상 이렇게 내용이 가려진다.
Wrapper.js
import React from 'react';
function Wrapper({ props }) {
const style = {
border: '2px solid black',
padding: '16px',
};
return (
<div style={style}>
{props.children}
</div>
)
}
export default Wrapper;
이렇게 자식 컴포넌트에 props.children을 넣어주면 겹치지 않게 된다.
:특정 조건에 따라 다른 결과물을 렌더링 하는 것
App.js => 부모
import React from 'react';
import Hello from './Hello';
import Wrapper from './Wrapper';
function App() {
return (
<Wrapper>
<Hello name="react" color="red" isSpecial={true}/>
<Hello color="pink" />
</Wrapper>
)
}
export default App;
Hello.js => 자식
import React from 'react';
function Hello({ color, name, isSpecial }) {
return (
<div style={{ color }}>
{ isSpecial ? <b>*</b> : null }
안녕하세요 {name}
</div>
);
}
Hello.defaultProps = {
name: '이름없음'
}
export default Hello;
export로 Hello를 내보내고, 부모는 import로 Hello를 받는다.
부모 컴포넌트에서 Hello안에 값을 넣고,
자식은 그 값들을 매개변수로 받는다. (props)
그리고 중간에 삼항연산자를 활용하여 조건에 따라 렌더링 할 수 있다.
(isSpecial이 true면? *를 굵게 출력하고, 아니라면 null)
:컴포넌트에서 보여줘야 하는 내용이 사용자의 반응(클릭, 입력 등)에 따라 달라져야 할 때 활용한다.
useState는 리액트의 Hook중 하나이다.
useState를 사용 할 때에는 상태의 기본값을 파라미터로 넣어서 호출해준다.
이 함수를 호출해주면 배열이 반환된다.
Counter.js
import React from 'react';
function Counter() {
const onIncrease = () => {
console.log('+1')
}
const onDecrease = () => {
console.log('-1');
}
return (
<div>
<h1>0</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;
이렇게 useState를 사용하지 않고, 함수만 선언했을 때는 console만 찍히게 된다.
이벤트를 만들어보자! ▼
Counter.js
import 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;
const로 선언하여 useState를 만든다.
첫번째 원소는 현재 상태, 두번째 원소는 setter함수이다.
setter함수는 파라미터로 전달 받은 값을 최신 상태로 설정해준다.
useState안에는 기본, 초기값을 넣어준다.
이 코드의 경우 number:현재상태, setNumber:setter함수, 0:초기값이다.
onIncrease함수가 실행될 때, setNumber함수가 실행되며
전달받은 값을 최신 상태로 설정해준다.
:input태그는 사용자가 값을 입력할 수 있는 공간이다.
사용자가 입력한 값을 받아와 화면을 변화시켜야 한다.
input은 onChange라는 이벤트를 사용한다.
이벤트 객체 e를 파라미터로 받아와서 사용할 수 있는데, e.target.value를 조회하면 현재 input에 입력한 값이 출력된다.
InputSample.js
import React, { useState } from 'react';
function InputSample() {
const [text, setText] = useState('');
const onChange = (e) => {
setText(e.target.value);
};
const onReset = () => {
setText('');
};
return (
<div>
<input onChange={onChange} value={text} />
<button onClick={onReset}>초기화</button>
<div>
<b>값: {text}</b>
</div>
</div>
);
}
export default InputSample;
input에 onChange값을 넣어주고, onChange라는 함수를 할당한다.
onChange함수는 e를 파라미터로 받고, setText함수에 e.target.value를 넣어 input으로 받은 값을 최신값으로 나타내도록 한다.
:input의 개수가 여러개가 됐을 때는, useState를 여러번 사용하고, onChange도 여러개 만들어서 사용해야 한다.
하지만 더 좋은 방법으로는,
input에 name을 설정하고, 이벤트가 발생했을 때 이 값을 참조하는 것이다.
InputSample.js
import React, { useState } from 'react';
function InputSample() {
const [inputs, setInputs] = useState({
name: '',
nickname: ''
});
const { name, nickname } = inputs; // 비구조화 할당을 통해 값 추출
const onChange = (e) => {
const { value, name } = e.target; // 우선 e.target 에서 name 과 value 를 추출
setInputs({
...inputs, // 기존의 input 객체를 복사한 뒤
[name]: value // name 키를 가진 값을 value 로 설정
});
};
const onReset = () => {
setInputs({
name: '',
nickname: '',
})
};
return (
<div>
<input name="name" placeholder="이름" onChange={onChange} value={name} />
<input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
<button onClick={onReset}>초기화</button>
<div>
<b>값: </b>
{name} ({nickname})
</div>
</div>
);
}
export default InputSample;
useState에서는 문자열이 아니라 객체 형태로 관리해야 한다.
리액트에서 객체를 수정해야 할 때에는,
단순 얕은 복사로 수정할 수 없다.
따라서 새로운 객체를 만들고, 스프레드 ...문법을 사용하여 불변성을 지켜주어야 한다.
이 코드는,
1.input에서 사용자가 입력한 값을 받아 나타내기 위해 useState를 만들고,
이때 받아오는 방법은 같으나 받아올 값이 다른 '이름'과 '닉네임'이 있다.
2.useState를 만들어 안에 객체를 넣는다. 객체 안에는 '이름'과 '닉네임'정보를 담는다. 이때 이 객체는 여러개가 될 수 있다.
3.구조분해할당을 통해 값을 추출한다. useState의 기본값 '이름'과 '닉네임'이 inputs이 되어 현재 값이 되는 것
4.onChange함수를 만들고 이벤트를 파라미터로 넣는다.
우선 e.target에서 name과 value를 추출한다.
setInput setter함수를 호출하고 안에 변하는 최신값을 객체로 넣어준다.
...문법을 사용하여 얕은 복사를 하고, [name]:value로 name키를 가진 값을 value로 설정한다. 이렇게 복사한 값을 최신값으로 설정한다.
5.input안에 값을 넣어주는데, 둘 다 onChange 이벤트에 onChange함수를 넣어주고, value 값을 각각 '이름'과 '닉네임'으로 잡아준다.