- Container / Presentational 패턴
소스코드를 자바스크립트(기능)과 JSX(UI)로 나누는 방법
파일이 나눠져 있어도 하나로 합쳐져서 실행되어야한다.
하나로 합쳐서 실행하는 방법은 부모컴포넌트에 자식컴포넌트를 불러오는 것이다.
💡 부모 컴포넌트와 자식 컴포넌트
→ import되어 불려가는 컴포넌트를 자식 컴포넌트라고 합니다.
반면 import하여 불러오는 컴포넌트를 부모 컴포넌트라고 합니다. 자식컴포넌트는 부모 컴포넌트 안에 포함되는 구조 입니다.
우리 눈에는 자식이 합쳐진 부모컴포넌트가 보이는 것!
컴포넌트를 2개로 나누면서 데이터와 기능의 연결고리가 끊어지게 된다.
그렇다면 함수 연결 방법은?
props
부모 컴포넌트가 자식 컴포넌트에게 물려주는 변수/함수
부모 컴포넌트가 props를 물려줄 때는 객체로 묶여서 넘기게 된다.
props 내려주기_부모컴포넌트
//부모 컴포넌트 _ container 부분
const BoardWrite = ()=>{
const [writer, setWriter ] = useState()
const handlechangeWriter = (e)=>{
writer = e.target.value
setWriter(writer)
}
return(
// 자식 컴포넌트 _ presenter 컴포넌트
// 본격적으로 props를 내려주는 부분입니다.
<BoardWriteUI propsName={handlechangeWriter}/>
)
}
위와 같이 props를 넘기게 되면, props = { propsName : handlechangeWriter } 형태의 객체로 넘어가게 된다.
props 받아오기_자식컴포넌트
//자식컴포넌트 _ presenter 부분
//파라미터 부분에 props를 적어주셔야 받아 올 수 있습니다.
const BoardWriteUI = (props)=>{
return(
<Wrapper>
<Writer
type = "text"
placeholder = "작성자를 적어주세요"
// 본격적으로 props를 내려받는 부분입니다.
onChange = {props.propsName}
/>
</Wrapper>
)
}
파라미터 부분에 props를 적지 않으면 받아 올 수 없으니 주의 해야한다.
또한 객체로 넘어오기 때문에 받아온 props를 사용하려면 객체의 속성을 꺼내오는 것 처럼 사용해줘야한다.
따라서 props.propsName 형태로 사용해야 한다.
잠깐!
리액트의 단방향 데이터 흐름
리액트는 데이터 흐름이 단방향 구조이다.
부모가 자식에게만 줄 수 있다.(역방향 불가)
리액트의 데이터 흐름이 단방향 구조이기때문에 우리가 에러를 캐치하기가 더 쉽고, 보기에 더 깔끔합니다.
- components/commons : 공통으로 사용될 수 있는 컴포넌트
컴포넌트 명은 대문자로 시작한다.
개별 컴포넌트는 이름이 동일하면 안되므로 작성에 주의
import BoardWrite from "../../src/components/units/board/write/BoardWrite.container";
//페이지 컴포넌트
export default function GraphQlMutationPage() {
return <BoardWrite />;
}
import { gql, useMutation } from "@apollo/client";
import { useState } from "react";
import BoardWriteUI from "./BoardWrite.presenter";
const 나의그래프ql셋팅 = gql`
mutation createBoard($writer: String, $title: String, $contents: String) {
createBoard(writer: $writer, title: $title, contents: $contents) {
_id
number
message
}
}
`;
export default function BoardWrite() {
const [writer, setWriter] = useState("");
const [title, setTitle] = useState("");
const [contents, setContents] = useState("");
const [나의함수] = useMutation(나의그래프ql셋팅);
const onClickSubmit = async () => {
const result = await 나의함수({
variables: {
writer: writer,
title: title,
contents: contents,
},
});
console.log(result);
};
const onChangeWriter = (event) => {
setWriter(event.target.value);
};
const onChangeTitle = (event) => {
setTitle(event.target.value);
};
const onChangeContents = (event) => {
setContents(event.target.value);
};
return (
<BoardWriteUI
aaa={onClickSubmit}
bbb={onChangeWriter}
ccc={onChangeTitle}
ddd={onChangeContents}
/>
);
}
export default function BoardWriteUI(props) {
return (
<div>
작성자: <input type="text" onChange={props.bbb} />
제목: <input type="text" onChange={props.ccc} />
내용: <input type="text" onChange={props.ddd} />
<button onClick={props.aaa}>GRAPHQL-API(동기) 요청하기</button>
</div>
);
}
컴포넌트를 분리해놓으면,
코드를 한눈에 확인할 수 있고 어느 부분에서 error가 발생했는지 확인하기 더 쉬워진다!