providers와 같은 컴포넌트들로 싸고 싸면서 작업을 하게 되어 상태관련 로직 관리에 어려움을 겪었음. 좀 더 단순화 하기 위해 hooks가 나오게 됨.
lifeCycle method와 같이 관련없는 로직들이 포함될 수 있는 코드들은 버그가 쉽게 발생함.
useState() : () 안에는 initial state를 넣어주면 된다.
만약 함수를 initial state로 지정하고 싶을 경우,
useState(()=> 함수()) 이렇게 사용하면 된다.
이 useState를 const [] 배열로 정의하고 배열의 첫 번째 변수는 initial state의 값을 담을 변수이고 두 번째 변수는 그 initial state 값의 변화를 받아 initial stete를 갱신해 줄 변수의 이름이다.
예시 :
const [count, setCount] = useState(() => 사용할 함수());
해당 state를 화면에 출력하기 위해서는 function형 함수 내에 return 안의 태그에 {initial state 값을 담고 있는 변수 이름}을 넣어준다.
예시 :
const App = () => {
const [count, setCount]= useState(10);
return(
<div>
<button onClick = {() => setCount(count+1)}>+</button>
<div>{count}</div>
</div>
);
}
setCount를 저렇게 정의할 경우 다른 기능들이 더해질 때 중복되어 적용될 가능성이 있으므로 콜백함수로 변수를 지정해서 사용하면 버그가 생길 가능성이 줄어든다.
예시 :
const App = () => {
const [count, setCount]= useState(10);
return(
<div>
<button
onClick = {() => setCount(currentCount => currentCount + 1)}
>+</button>
<div>{count}</div>
</div>
);
}
const App = () => {
const [{count, count2}, setCount]= useState({count:10, count2:20});
return(
<div>
<button
onClick = {() => setCount(currentState(여기서 객체로 바뀜) => ({count: currentState.count + 1)})}
>+</button>
<div>count 1 : {count}</div>
<div>count 2 : {count2}</div>
</div>
);
}
여기서 주의해야 하는 점은 useState 함수 내에 const로 함께 정의되어 있는 객체더라도 실제 event 안에서 사용시 event 안에서 정의된 객체만 화면에 나타남
위의 예시를 보면 count와 count2는 같이 useState를 통해 객체에 들어있지만
onClick event에서는 count만 불러왔기때문에 count2의 값은 화면에 나타나지 않음
만약에 count2의 값도 같이 나타내고 싶을 경우 es6 문법의 spread를 사용해서 불러올 수 있음
예시 :
<button
onClick = {() => setCount(currentState(여기서 객체로 바뀜) =>
({...currentState,
count: currentState.count + 1)})}
>+</button>
const App = () => {
const [count, setCount]= useState(10);
const [count2, setCount2] = useState(20);
return(
<div>
<button
onClick = {() => {
setCount(c=> c+1);
setCount2(c=> c+1);
}}
>+</button>
<div>count 1 : {count}</div>
<div>count 2 : {count2}</div>
</div>
);
}
const App = () => {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
return (
<div>
<input
name = "email"
value = {email}
onChange = {e=> setEmail(e.target.value)}
/>
<input
type="password"
name="password"
value={password}
onChange={e=> setPassword(e.target.value)}
/>
</div>
);
}
코드가 길고 시간도 많이 걸린다.
재사용할 함수를 정의할 파일을 만든다. 일반적으로 use를 사용하여 파일 이름을 만든다. 예시 : useForm.js
import {useState} from 'react';
export const useForm = (initialValues(지정하고 싶은 변수 이름)) =>
{
const [values, setValues] = useState(initialValues);
return [values, e => {
setValues({
...values,
[e.target.name] : e.target.value
})
}]
}
import React, {useState} from "react";
import {useForm} from "./useForm";
const App = () => {
const [values, handleChange] = useForm({email: '', passwor: ''});
return (
<div>
<input
name = "email"
value = {values.email}
onChange = {handleChange}
/>
<input
type="password"
name="password"
value={values.password}
onChange={handleChange}
/>
</div>
);
}