function reducer(state,action){
return { ... }; //불변성을 지키면서 업데이트한 새로운 상태를 반환
}
{
type:"INCREMENT"
//다른 값들이 필요하다면 추가로 들어감
}
useReducer에서 사용하는 액션 객체는 반드시 type을 지니고 있을 필요는 없다. 심지어 객체가 아니라 문자열이나 숫자여도 상관없다.
function reducer(state,action){
switch(action.type){
case 'INCREMENT':
return { value: state.value + 1};
case 'DECREMENT':
return { value: state.value - 1};
default:
return state;
}
}
const useReducer = () => {
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>
</div>
);
};
export default useReducer;
import React, { useReducer } from 'react';
function reducer(state,action){
return{
...state,
[action.name]: action.value
};
}
const ReducerInfo = () => {
const [state,dispatch] = useReducer(reducer,{
name:'',
nickname: '',
phone: ''
})
const {name, nickname,phone,address,email} = state;
const onChange = e => {
dispatch(e.target);
}
return (
<div>
<form action="">
<input name="name" value={name} onChange={onChange} type="text" />
<input name="nickname" value={nickname} onChange={onChange} type="text" />
<input name="phone" value={phone} onChange={onChange} type="number" />
<input name="address" value={address} onChange={onChange} type="address" />
<input name="email" value={email} onChange={onChange} type="email" />
</form>
<div>
<b>이름</b>: {name}
<b>닉네임</b>: {nickname}
<b>핸드폰번호</b>: {phone}
<b>주소</b>: {address}
<b>이메일</b>: {email}
</div>
</div>
);
};
export default ReducerInfo;
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)}
</div>
</div>
);
};
export default Average;
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('');
}
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;
const Average = () => {
const [list,setList] = useState([]);
const [number,setNumber] = useState('');
//onChange함수는 컴포넌트가 처음 랜더링 될 때만 함수를 생성하고 이후는 재활용
const onChange = useCallback(e => {
setNumber(e.target.value);
},[])
//onInsert 함수는 number 또는 list가 바뀔때만 함수 생성
const onInsert = useCallback(e =>{
const nextList = list.concat(parseInt(number));
setList(nextList);
setNumber('');
},[number,list])
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;