App.js 에서 값을 내려줄 수는 없을까?
- props으로 전달할 값들을 객체로 만들면 더 깔끔하게 전달가능함.
- props로 만들어준 후에 spread 시켜서 return 값에 넣어주기.
ex) {...counterProps}
const counterProps = {
a: 1,
b: 2,
c: 3,
d: 4,
e: 5,
initialValue: 5,
};
return (
<div style={style.App}>
<MyHeader />
<Counter {...counterProps} />
{}
<MyFooter />
</div>
);
counter.js에서는 ?
- App.js 에서 props를 전달인자로 받아올수 있음.
- props는 전달받을 때 객체 형태로 들어옴. 따라서 접근할 때 점표기법으로 접근가능.
- count 상태: 0에서 출발, 1씩 증가, 1씩 감소, count 상태
import React, { useState } from "react";
const Counter = (props) => {
console.log(props);
const [count, setCount] = useState(0);
console.log("counter 호출!");
const onIncrease = () => {
setCount(count + 1);
};
const onDecrease = () => {
setCount(count - 1);
};
const [count2, setCount2] = useState(props.initialValue);
const onIncrease2 = () => {
setCount2(count2 + 2);
};
const onDecrease2 = () => {
setCount2(count2 - 2);
};
- 비구조화할당으로 가져올 수도 있음
: props 객체에서 initialValue만 꺼내쓴것임
const Counter = ({ initialValue }) => {
const [count, setCount] = useState(initialValue);
props로 내려주기로한 값이 누락되었을 때를 대비할 때: counter.js 파일 내에서 defaultProps를 설정해주면 됨.
Counter.defaultProps = {
initialValue: 0,
};
동일 구조를 state로 받는방법
const [state, setState] = useState({
author: "",
content: "",
});
import { useState } from "react";
const DiaryEditor = () => {
const [state, setState] = useState({
author: "",
content: "",
});
- 아래 두줄을 위처럼 바꿀 수 있음.
const [author, setAuthor] = useState("");
const [content, setContent] = useState("");
return (
<div className="DiaryEditor">
<h2>오늘의 일기</h2>
<div>
<input
name="author"
value={author}
onChange={(e) => {
setAuthor(e.target.value);
}}
/>
</div>
<div>
<textarea
name="content"
value={content}
onChange={(e) => {
setContent(e.target.value);
}}
></textarea>
</div>
</div>
);
};
export default DiaryEditor;
- 받을 때는 아래와 같이 setState({content: e.target.value, author: state.author})
이런식으로 하면 됨
특정값만 변경하고 싶을 때는? ...state,
- state값이 2개만있을 때는 둘 다 적어주는 것이 힘들지 않을 수 있으나, 여러개가 있는 경우에는 하나하나 다 적어줘야하는 번거로움이 있음. 따라서 spread syntax를 써주면 됨.
- 주의할 점: ...state를 먼저 해주고 나서, 변경하고 싶은 값(author: e.target.value)를 적어줘야 반영이 됨.
...state를 뒤에 써주면 ...state에 기존값이 또 반영이 되기때문에 반영이 안됨.
return (
<div className="DiaryEditor">
<h2>오늘의 일기</h2>
<div>
<input
name="author"
value={state.author}
onChange={(e) => {
setState({
...state,
author: e.target.value,
});
}}
/>
</div>
<div>
<textarea
name="content"
value={state.content}
onChange={(e) => {
setState({
author: state.author,
content: e.target.value,
});
}}
></textarea>
</div>
</div>
);
};
export default DiaryEditor;
event handler도 묶어버리기
const handleChangeState = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
};
return (
<div className="DiaryEditor">
<h2>오늘의 일기</h2>
<div>
<input
name="author"
value={state.author}
onChange={handleChangeState}
/>
</div>
<div>
<textarea
name="content"
value={state.content}
onChange={handleChangeState}
></textarea>
</div>
</div>
);
};