// ./src/components/Example6.jsx
export default function Example6() {
// reducer: state를 변경하는 로직이 담겨있는 함수
const reducer = (state, action) => {
if(action.type === 'PLUS'){
return {
count: state.count+1
};
}
return state;
}
// dispatch: action 객체를 넣어서 실행
// -> action은 객체이고 필수 프로퍼티로 type 가짐
const [state, dispatch] = useReducer(reducer, {click: 0});
return(
<div>
<p>You clicked {state.count} times</p>
<button onClick={click}>Click Me</button>
</div>
);
function click(){
dispath({type: 'PLUS'});
}
}
// ./src/components/Example7.jsx
function sum(persons){
return persons.map(person => person.age).reduce((l, r) => l+r, 0);
}
export default function Example7(){
const [value, setValue] = useState('');
const [persons] = useState([
{name: 'Mark', age: 39},
{name: 'Hanna', age: 28},
]);
const count = useMemo(() => {
return sum(persons);
}, [persons]); // persons 변할 때만 다시 sum 실행
return(
<div>
<input value={value} onChange={change} />
<p>{count}</p>
</div>
);
function change(e){
setValue(e.target.value);
}
}
const click = useCallback(() => {
console.log(value);
}, []); // 안의 함수를 언제 새로 설정할지 dependency list에 의존적으로 결정
// -> component 최적화에서 다시 학습
// ./src/components/Example8.jsx
export default function Example8(){
const [value, setValue] = useState('');
const input1Ref = createRef();
const input2Ref = useRef();
console.log(input1Ref.current, input2Ref.current);
return(
<div>
<input value={value} onChange={change} /> // controlled
<input ref={input1Ref} /> // uncontrolled + createRef() -> ref 계속 새로 만들어 render될 때 참조
<input ref={input2Ref} /> // uncontrolled + useRef() -> render 반복해도 같은 ref 유지하며 참조
</div>
);
function change(e){
setValue(e.target.value);
}
}
🌟 useRef, useCallback, useMemo -> render 사이의 상태 유지하는 역할
(class에서는 내부의 render가 돌며 자동으로 유지하지만, function에서는 계속 새로 생성되는 성질 있으므로 이들을 사용해 유지 필요!)