계산된 속성명 - 속성명을 미리 계산을 해서 그거에 맞는 데이터를 넣는다
❗️ 보기 전 알아야될 점!
모든태그에는 name 속성이 존재하지 않는다.
무작정 계산된 속성명 써서 name부여한다음 name 가져와서 뭘 해야겠다라는 생각XX
input태그가 아닌 곳에서 계산된 속성명을 쓸 경우 on~ 이벤트를 걸어준 다음 event console를 찍어보고 event.target 안에 있는 속성들을 보고 난 다음 거기에 내가 사용할 수 있는 속성들이 있는지 판단하고 해당 속성을 사용해야한다.(div태그는 name이 없음)
계산된 속성명을 사용하지 않으면 비슷한 구조의 함수와 state를 input태그별로 생성해야된다.
(동일한 동작을 하고 있는데 state에 넣어주는 값만 다름)
const [inputId, setInputId] = useState("");
const [inputPw, setInputPw] = useState("");
const handleInputId = e => {
setInputId(e.target.value);
};
const handleInputPw = e => {
setInputPw(e.target.value);
};
1. state를 전부 포괄하는 useInput
로 관리
2. useState는 객체로 관리 ({})
3. 객체 키는 기존에 만들었던 state 키로 생성
4. handleInput
함수 선언 - 각각에 input
에서 이벤트가 이러나면 setUseInput
에 안에 있는 내용을 변경 시켜줄때 사용
const [useInput, setUseInput] = useState({
id: '',
pw: '',
});
const handleInput = e => {
setUseInput();
};
5. 현재는 하나의 함수 두개의 input
이기 때문에 사용자는 어떤 input
에 값을 넣고 있는지 알지만 컴퓨터입장에선 어디에 값이 들어오는지 모른다. 그것을 알게해주기 위해 속성값을 넣어줘야 한다.
6. console.log(e)
를 찍어보면 이벤트 객체가 나오는데 우린 여기서 event.target.value
를 가져오는 것이다.
const handleInput = e => {
console.log(e)
};
target
이input
이라고 되어있다. 왜냐면event.target
은 이벤트가 일어나는 곳을 의미하기 때문
7. 현재 이벤트타겟이 어디서 일어나는지만 알고 어떤 데이터를 넣어야되는지는 모르는 상태임
-> 우선 console.log
보면 input
이 갖고 있는 속성들을 볼 수가 있는데 여기서 name
을 이용해서 input
태그가 어떤 이름을 갖고있게 부여를 해줘야함.
8. name
의 값은 state의 키값으로 설정
<input
className="userInput"
type="text"
name="id"
placeholder="ID"
onChange={handleInput}
/>
<input
className="userInput"
type="password"
name="pw"
placeholder="Password"
onChange={handleInput}
/>
설정 후 id input에 값을 넣으면 어떤 name을 갖고있는 input에서 이벤트가 일어났는지 handleInput
함수에서 알 수 있다.
(console에 name이 설정된 것을 확인 할 수 있다.)
아래 콘솔 찍으면 위에 이미지에 있는 name
값 가져와서 찍힘 ->id
이런식으로
const handleInput = e => {
console.log(e.target.name);
};
9. 이제 state에 자리에 맞게 넣어주기만 하면 된다.
key:value
형태로 넣어줌const { name, value } = e.target;
name
과 value
를 준다. const [useInput, setUseInput] = useState({
id: '',
pw: '',
});
const handleInput = e => {
const { name, value } = e.target;
setUseInput({ name:value });
};
❗️ 이렇게까지만 가져오면 나는 pw에 값을 넣는데 계속 id에만 값이 들어가게된다.
(사진에서는 email에 넣었는데 계속 name에 들어가는 상황)
{ ...useInput,[name]:value }
이렇게 써줘야함useInput
state를 가져와서 ...useInput
로 복제해준 다음 그곳에[name]:value
로 업데이트하여 맞는 값을 넣어주겠다는 뜻 const [useInput, setUseInput] = useState({
id: '',
pw: '',
});
const handleInput = e => {
const { name, value } = e.target;
setUseInput({ ...useInput,[name]:value });
};
만약, { ...useInput, name:value }
이렇게 쓰게 될 경우 name이 선언은 됐지만 해당 값이 읽히지 않는다는 워닝이 뜸
왜냐하면 객체에 변수인 key를 name로 넣으면 string이라고 인식하여 name(string)이라고 고정으로 들어가 버린다.
그래서 변수라는 것을 알려주기 위해 [name]
으로 작성해야 함
❌ 잘못된 예시
아래처럼 입력하고 id input에 값을 1이라고 입력하면 e.target.name
에는 name 값인 id
를 가져오고 e.target.value
는 value값인 1이 들어오면서 useInput
을 바꿔줄것인데 아래와 같이 사용하면 안된다.
const [useInput, setUseInput] = useState({
id: '',
pw: '',
});
const handleInput = e => {
setUseInput({e.target.name : e.target.value});
};
const [inputValues, setInputValues] = useState({
id: '',
pw: '',
});
const handleInput = e => {
const { name, value } = e.target;
setInputValues({ ...inputValues, [name]: value });
};
const Login = () => {
return (
<input
className="userInput"
type="text"
name="id"
placeholder="ID"
onChange={handleInput}
/>
<input
className="userInput"
type="password"
name="pw"
placeholder="Password"
onChange={handleInput}
/>
)
}
prev
라는것은 setUseInput
(setState)가 갖고있는 특징 중 하나(다른이름을 써도되지만 컨벤션임)(prev)
에 파마미터값을 넘겨주지 않더라도 (prev)
로 인자를 넣게되면 이전값을 가져오는 특징을 가지고 있다.useInput
를 무조건 사용하지 않아도됨 const [useInput, setUseInput] = useState({
id: '',
pw: '',
});
const handleInput = e => {
const { name, value } = e.target;
setUseInput((prev)=>({ ...prev,[name]:value }));
};
모달창 구현 시
const [isModelOpen, setIsModelOpen] = useState(false);
1. 기존 사용방법
const handelModal = () => {
setIsModelOpen(!isModelOpen)
}
2. 함수형 업데이트 사용방법
const handelModal = () => {
setIsModelOpen((prev) => !prev)
}
저도 개발자인데 같이 교류 많이 해봐요 ㅎㅎ! 서로 화이팅합시다!