이렇게 나눠버리면 onclick, onchange등 함수를 쓸수 없게 되는데
→ 부모 컴포넌트에서 함수, 변수 라던지 데이터들을 전달해 줄 수있다.
props = { aaa: handleChageWriter }
라고 만들어지게 됨 (키와 벨류를 가진 객체로 저장됨)props
가 presenter 컴포넌트에 전달되게 됨.props.aaa
에는 handleChageWriter 가 들어있는 것. → 이것을 실행.자식이 부모에게 넘겨주는 것음 없음
→ 리액트에서 데이터의 흐름은
단방향구조
부모가 자식에게만 줄 수 있는 것
💡 props 구조 분해 할당으로 받아오기
→ 구조 분해 할당으로 props를 받아오게 되면, props.propsName이 아닌 propsName만 적으면 되기 때문에 조금 더 편리하게 사용할 수 있습니다.
→ 또한 , 구조 분해 할당으로 props를 받아오면 필요한 것만 받아올 수 있습니다.
부모컴포넌트는 하나지만, 자식 컴포넌트가 여러개인 경우 구조분해 할당이 props를 내려주고 받는데 조금더 편리 합니다.
퀴즈 - props 부분이랑 연관
input 부분이 다 입력되었을때 → 버튼 색깔 노랑
presenter → isActive = {props} 를 버튼에 줌
// 이모션
export const SubmitButton = styled.button`
background-color: ${ (props) => props.isActive === true ? "yellow" : "" };
/* 함수를 강제로 만들고 그 안에 props */
/* 삼항 연산자로 isActive가 true라면 yellow, false = "" */
/* props.isActive: isActive는 key값...*/
`;
props 흐름도
onChange에 입력값이 다 있다면 노란색으로 버튼 변경.
→ state의 동작원리와 관련된 퀴즈
state는 비동기로 작동하기 때문에 setState가 동기로 작동하게 되면 변경될때마다 바로바로 랜더링을 하기 떄문에 비효율적
→ 따라서 임시저장소에 모아두었다가 (state?) 코드를 끝까지 읽고 한번에 바꿔서 랜더링
export default function BoardWrite() {
const [isActive, setIsActive] = useState(false)
const [writer, setWriter] = useState("")
const [title, setTitle] = useState("")
const [contents, setContents] = useState("")
const [data, setData] = useState({});
const [callGraphql] = useMutation(CREATE_BOARD)
const onClickGraphqlApi = async () => {
const result = await callGraphql({
variables: { writer: writer, title: title, contents: contents }
})
console.log(result);
setData(result.data.createBoard);
};
// state는 임시저장공간에 넣어놨다가 함수가 끝난 후에 그 값을 적용시키고 다시 새롭게 컴퍼넌트를 만들어서
// setWriter 를 넣게 되면 임시저장 공간에 가게되고 그렇다면 onChangeWriter 안에 writer는 아직
// 할당이 되지 않아서 조건이 이상하게 됨 -> 해결: writer : event.target.value로.
// 중요: state는 바로바로 바뀌는 것이 아님, 함수가 끝나고 리랜더링!
const onChangeWriter = (event) => {
setWriter(event.target.value)
if (event.target.value(~~writer~~) && title && contents) {
setIsActive(true)
}else{
setIsActive(false)
}
}
const onChangeTitle = (event) => {
setTitle(event.target.value)
if (writer && event.target.value(~~title~~) && contents) {
setIsActive(true)
}else{
setIsActive(false)
}
}
const onChangeContents = (event) => {
setContents(event.target.value)
if (writer && title && event.target.value(~~contents~~)) {
setIsActive(true)
}else{
setIsActive(false)
}
}
// Error code : 바깥에서 처리했더니 에러. State의 값이 너무 많이 바뀜.to many render
// if (writer && title && contents) {
// setIsActive(true)
// }else{
// setIsActive(false)
// }
💡
setstate의 비동기적 특성
아래의 버튼을 클릭하면 어떤값이 나올까요?
→ 정답은 1.
setState가 비동기적 특성을 갖기때문입니다.
(동기적으로 작동했다면 코드를 읽고 바로 내려가서 또 1을 더하고 또 1을 더해 3이 나왔을 것)
export default function stateTest(){
const [value,setValue]=useState(0)
const onClick = () => {
setValue(value+1)
setValue(value+1)
setValue(value+1)
}
return (
<div className="App">
<button onClick={onClick}>+</button>
<h1>{value}</h1>
</div>);
}