useState 사용하기
// Counter.js
import React, { useState } from "react";
const Counter = () => {
const [value, setValue] = useState(0);
return (
<div>
<p>
현재 카운터 값은 <b>{value}</b>입니다.
</p>
<button onClick={() => setValue(value + 1)}>+1</button>
<button onClick={() => setValue(value - 1)}>-1</button>
</div>
);
};
export default Counter;
// App.js
import React from "react";
import Counter from "./Counter";
const App = () => {
return <Counter />;
};
export default App;
useState 여러번 사용하기
// Info.js
import React, { useState } from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickanme] = useState("");
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickName = e => {
setNickanme(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName} />
<input value={nickname} onChange={onChangeNickName} />
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
// App.js
import React from "react";
import Info from "./Info";
const App = () => {
return <Info/>;
};
export default App;
useEffect 사용하기
// Info.js
import React, {useState, useEffect} from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickanme] = useState("");
// componentDidMount, componentDidUpdate를 합친형태
useEffect(() => {
console.log('렌더링이 완료되었습니다.!');
console.log({
name, nickname
})
})
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickName = e => {
setNickanme(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickName}/>
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
useEffect, 마운트될 때만 실행하고자 할 때
// Info.js
import React, {useState, useEffect} from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickanme] = useState("");
// componentDidMount, componentDidUpdate를 합친형태
useEffect(() => {
console.log('마운트 될 때만 실행됩니다.!');
}, []);
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickName = e => {
setNickanme(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickName}/>
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
useEffect 특정값이 갱신될 때만 수행하고 싶을 때
// Info.js
import React, {useState, useEffect} from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickanme] = useState("");
// 두번째 파라미터에 값을 넣으면 해당 값이 바뀔때에만 수행한다.
useEffect(() => {
console.log('최초 실행시점과, name이 갱신 될 때만 실행됩니다.!');
}, [name]);
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickName = e => {
setNickanme(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickName}/>
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
useEffect, 뒷정리하기
// Info.js
import React, {useState, useEffect} from "react";
const Info = () => {
const [name, setName] = useState("");
const [nickname, setNickanme] = useState("");
// 컴포넌트가 언마운트되거나 업데이트되기 직전에 수행된다.(뒷정리 작업을 할 경우 사용한다.)
useEffect(() => {
console.log('effect');
console.log(name);
return () => {
console.log('cleanup');
console.log(name);
};
});
const onChangeName = e => {
setName(e.target.value);
};
const onChangeNickName = e => {
setNickanme(e.target.value);
};
return (
<div>
<div>
<input value={name} onChange={onChangeName}/>
<input value={nickname} onChange={onChangeNickName}/>
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
// App.js
import React, { useState } from "react";
import Info from "./Info";
const App = () => {
const [visible, setVisible] = useState(false);
return (
<div>
<button
onClick={() => { // 버튼을 눌러 컴포넌트가 사라지면 cleanup, 나타나면 effect가 로그에 찍힌다.
setVisible(!visible);
}}
>
{visible ? "숨기기" : "보이기"}
</button>
<hr />
{visible && <Info />}
</div>
);
};
export default App;
useReducer
// Counter.js
import React, {useReducer} from "react";
function my_reducer(state, action) {
switch (action.type) {
case 'INCREMENT' :
return {value: state.value + 1};
case 'DECREMENT' :
return {value: state.value - 1};
default:
return state;
}
}
const Counter = () => {
// useReducer의 첫번째 파라미터는 리듀서함수를 넣어주고, 두번째 파라미터는 초기값을 넣어준다.
const [state, dispatch] = useReducer(my_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>
</div>
);
};
export default Counter;
// App.js
import React from "react";
import Counter from "./Counter";
const App = () => {
return <Counter />;
};
export default App;
useReducer, 인풋상태 관리하기
// Info .js
import React, { useReducer } from "react";
function myReducer(state, action) {
//console.log(action); dispatch() 에서 넘긴 e.target가 넘어온다.
//console.log(state); {name: , nickname}의 오브젝트가 넘어온다.
return {
...state,
[action.name]: action.value
};
}
const Info = () => {
const [state, dispatch] = useReducer(myReducer, { name: "", nickname: "" });
const {name, nickname} = state;
//console.log( useReducer(myReducer, { name: "", nickname: "" })); 첫번째는 초기화한 오브젝트가, 2번째는 함수(dispatch)가 반환된다.
//console.log( state );
const onChange = e => {
dispatch(e.target);
};
return (
<div>
<div>
<input name="name" value={name} onChange={onChange} />
<input name="nickname" value={nickname} onChange={onChange} />
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
// App.js
import React from "react";
import Info from "./Info";
const App = () => {
return <Info />;
};
export default App;
useMemo : 컴포넌트 내부에서 발생하는 연산을 최적화 하는 함수
// Average.js
import React, {useState} from "react";
const getAverage = numbers => {
console.log("평균값 계산");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = e => {
setNumber(e.target.value);
};
const onInsert = e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
return (
<div>
<input value={number} onChange={onChange}/>
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b> 평균값:</b> {getAverage(list)} // 입력값이 바뀔 때마다 onChange가 호출되고, number값이 변경되어 getAverage가 매번 호출된다.
</div>
</div>
);
};
export default Average;
// App.js
import React from "react";
import Average from "./Average";
const App = () => {
return <Average />;
};
export default App;
// Average.js
import React, { useState, useMemo } from "react";
const getAverage = numbers => {
console.log("평균값 계산");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = e => {
setNumber(e.target.value);
};
const onInsert = e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
};
// 두번째 인자값이 변경될 때에만, getAverage가 호출된다.
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} />
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b> 평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
// App.js
import React from "react";
import Average from "./Average";
const App = () => {
return <Average />;
};
export default App;
useCallback : 렌더링 성능을 최적화하기 위해 사용하는 함수
// Average.js
import React, {useState, useMemo, useCallback} from "react";
const getAverage = numbers => {
console.log("평균값 계산");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback(
e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
},
[number, list] // number, list 둘 중 어느 하나가 변경될 때에만 함수 생성, 함수 내부에서 사용하는 변수는 2번째 인자에 반드시 포함시켜야 한다.
);
// 두번째 인자값이 변경될 때에만, getAverage가 호출된다.
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange}/>
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b> 평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
useRef : ref를 쉽게 사용할 수 있도록 해주는 함수
// Average.js
import React, {useState, useMemo, useCallback, useRef} from "react";
const getAverage = numbers => {
console.log("평균값 계산");
if (numbers.length === 0) return 0;
const sum = numbers.reduce((a, b) => a + b);
return sum / numbers.length;
};
const Average = () => {
const [list, setList] = useState([]);
const [number, setNumber] = useState("");
const inputEl = useRef(null);
const onChange = useCallback(e => {
setNumber(e.target.value);
}, []); // 컴포넌트가 처음 렌더링 될 때만 함수 생성
const onInsert = useCallback(
e => {
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber("");
inputEl.current.focus();
},
[number, list] // number, list 둘 중 어느 하나가 변경될 때에만 함수 생성
);
// 두번째 인자값이 변경될 때에만, getAverage가 호출된다.
const avg = useMemo(() => getAverage(list), [list]);
return (
<div>
<input value={number} onChange={onChange} ref={inputEl}/>
<button onClick={onInsert}>등록</button>
<ul>
{list.map((value, index) => (
<li key={index}>{value}</li>
))}
</ul>
<div>
<b> 평균값:</b> {avg}
</div>
</div>
);
};
export default Average;
useRef , 로컬 변수처럼 사용
// 클래스형태로 구현한 예제
import React, {Component} from "react";
class MyComponent extends Component {
id = 1
setId = (n) => {
this.id = n;
}
printId = () => {
console.log(this.id);
}
render() {
return (
<div>
Test
</div>
)
}
}
export default MyComponent;
// ref로 동일하게 구현한 예제
import React, {useRef} from "react";
const RefSample = () => {
const id = useRef(1);
const setId = (n) => {
id.current = n;
}
const printId = () => {
console.log(id.current);
}
return (
<div>
refSample
</div>
);
};
export default RefSample;
커스텀 Hooks 만들기
// useInputs.js
import {useReducer} from 'react';
function myReducer(state, action) {
return {
...state,
[action.name] : action.value
};
}
export default function useInputs(initialForm) {
const [state, dispatch] = useReducer(myReducer, initialForm);
const onChange = e => {
dispatch(e.target);
};
return [state, onChange];
}
// Info.js
import React from "react";
import useInputs from "./useInputs";
const Info = () => {
const [state, onChange] = useInputs({name: "", nickName: ""});
const {name, nickname} = state;
return (
<div>
<div>
<input name="name" value={name} onChange={onChange}/>
<input name="nickname" value={nickname} onChange={onChange}/>
</div>
<div>
<div>
<b>이름 : </b> {name}
</div>
<div>
<b>닉네임 : </b> {nickname}
</div>
</div>
</div>
);
};
export default Info;
최신 댓글