앞서 진행했던 체크박스기능 구현에서, 컴포넌트를 재활용하여 코드를 좀 더 보기좋게 만들어 보도록 하겠습니다.
import React, { useState, useMemo } from "react";
import styled from "styled-components";
function App() {
const [checkedList, setCheckedList] = useState([]);
const isCheckedAll = useMemo(
() => checkedList.length === 5,
[checkedList.length]
);
const changeHandler = ({ target }) => {
checkedList.includes(target.name)
? setCheckedList((prev) => prev.filter((item) => item !== target.name))
: setCheckedList((prev) => [...prev, target.name]);
};
const changeAllHandler = () => {
isCheckedAll === true
? setCheckedList([])
: setCheckedList(["checkA", "checkB", "checkC", "checkD", "checkE"]);
};
return (
<Main>
<CheckBoxAll
type="checkbox"
name="CheckAll"
onChange={changeAllHandler}
checked={isCheckedAll}
/>
<Content>
<CheckBoxA
type="checkbox"
name="checkA"
onChange={changeHandler}
checked={checkedList.includes("checkA")}
/>
<CheckBoxB
type="checkbox"
name="checkB"
onChange={changeHandler}
checked={checkedList.includes("checkB")}
/>
<CheckBoxC
type="checkbox"
name="checkC"
onChange={changeHandler}
checked={checkedList.includes("checkC")}
/>
<CheckBoxD
type="checkbox"
name="checkD"
onChange={changeHandler}
checked={checkedList.includes("checkD")}
/>
<CheckBoxE
type="checkbox"
name="checkE"
onChange={changeHandler}
checked={checkedList.includes("checkE")}
/>
</Content>
</Main>
);
}
export default App;
const Main = styled.div`
width: 100%;
height: 100%;
background-color: aliceblue;
`;
const CheckBoxAll = styled.input`
width: 100%;
`;
const Content = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background-color: antiquewhite;
`;
const CheckBoxA = styled(CheckBoxAll)``;
const CheckBoxB = styled(CheckBoxAll)``;
const CheckBoxC = styled(CheckBoxAll)``;
const CheckBoxD = styled(CheckBoxAll)``;
const CheckBoxE = styled(CheckBoxAll)``;
여기에서 전체선택을 제외한 각각의 체크박스는 스타일과 기능이 동일하다고 봤을때, 하나의 컴포넌트를 만들어서 통합 관리해 줄 수 있습니다.
하나의 체크박스 컴포넌트를 만들어 보겠습니다.
새로운 Checkbox.js 라는 파일을 만들어 줍니다.
import React from "react";
import styled from "styled-components";
const CheckBox = () => {
return ();
};
export default CheckBox;
여기서 check라는 새로운 체크박스 인풋을 만들어 주도록 하겠습니다.
const CheckBox = ({ checkedList, setCheckedList, children }) => {
return (
<Check
type="checkbox"
/>
);
};
export default CheckBox;
const Check = styled.input`
width: 100%;
`;
이제 부모 컴포넌트에서 필요한 요소들을 prop으로 전달받도록 하겠습니다.
필요한 요소들을 생각해봤을때 체크여부를 확인하기 위한 checkedList 와 체크를 눌렀을때 checkedList state에 값을 넣어줄 setCheckedList, 그리고 checkbox의 name을 대신할 children을 prop으로 받아옵니다.
import React, { useState, useMemo } from "react";
import styled from "styled-components";
import CheckBox from "./component/CheckBox"; //만들어둔 checkbox 컴포넌트를 import 해오기
function App() {
const [checkedList, setCheckedList] = useState([]);
const isCheckedAll = useMemo(
() => checkedList.length === 5,
[checkedList.length]
);
const changeAllHandler = () => {
isCheckedAll
? setCheckedList([])
: setCheckedList([
"checkOne",
"checkTwo",
"checkThree",
"checkFour",
"checkFive",
]);
};
return (
<Main>
<CheckBoxAll
type="checkbox"
name="CheckAll"
onChange={changeAllHandler}
checked={isCheckedAll}
/>
<Content>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkOne
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkTwo
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkThree
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkFour
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkFive
</CheckBox>
</Content>
</Main>
);
}
export default App;
const Main = styled.div`
width: 100%;
height: 100%;
background-color: aliceblue;
`;
const CheckBoxAll = styled.input`
width: 100%;
`;
const Content = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background-color: antiquewhite;
`;
import React from "react";
import styled from "styled-components";
const CheckBox = ({ checkedList, setCheckedList, children }) => {
return (
<Check
type="checkbox"
checked={checkedList.includes(children)}
/>
);
};
export default CheckBox;
const Check = styled.input`
width: 100%;
`;
이제 체크박스를 눌렀을때 작동할 함수 changeHandler를 만들어주겠습니다.
일단 onChange에 콜백함수로 changeHandler를 호출하는데, 이때 체크박스를 눌렀을때
checkedList 배열에 children 요소를 추가해줄 예정이니, children을 인수로 보내줍니다.
<Check
type="checkbox"
onChange={() => changeHandler(children)}
checked={checkedList.includes(children)}
/>
그리고 changeHandler 함수는 children 이라는 인수를 name이라는 매개변수로 받아 checkedList에 추가 또는 제거 해주면 되기 때문에
const changeHandler = (name) => {
checkedList.includes(name)
? setCheckedList((prev) => prev.filter((item) => item !== name))
: setCheckedList((prev) => [...prev, name]);
};
이렇게 해주면, 모든 체크박스의 상태관리를 각각의 체크박스가 아닌 부모컴포넌트에서 통합관리하고,
각각의 체크박스에서 함수를 통해 부모컴포넌트의 state값에 접근하도록 해주면 됩니다.
따라서
import React, { useState, useMemo } from "react";
import styled from "styled-components";
import CheckBox from "./component/CheckBox";
function App() {
const [checkedList, setCheckedList] = useState([]);
const isCheckedAll = useMemo(
() => checkedList.length === 5,
[checkedList.length]
);
const changeAllHandler = () => {
isCheckedAll
? setCheckedList([])
: setCheckedList([
"checkOne",
"checkTwo",
"checkThree",
"checkFour",
"checkFive",
]);
};
return (
<Main>
<CheckBoxAll
type="checkbox"
name="CheckAll"
onChange={changeAllHandler}
checked={isCheckedAll}
/>
<Content>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkOne
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkTwo
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkThree
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkFour
</CheckBox>
<CheckBox checkedList={checkedList} setCheckedList={setCheckedList}>
checkFive
</CheckBox>
</Content>
</Main>
);
}
export default App;
const Main = styled.div`
width: 100%;
height: 100%;
background-color: aliceblue;
`;
const CheckBoxAll = styled.input`
width: 100%;
`;
const Content = styled.div`
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
background-color: antiquewhite;
`;
import React from "react";
import styled from "styled-components";
const CheckBox = ({ checkedList, setCheckedList, children }) => {
const changeHandler = (name) => {
checkedList.includes(name)
? setCheckedList((prev) => prev.filter((item) => item !== name))
: setCheckedList((prev) => [...prev, name]);
};
return (
<Check
type="checkbox"
onChange={() => changeHandler(children)}
checked={checkedList.includes(children)}
/>
);
};
export default CheckBox;
const Check = styled.input`
width: 100%;
`;
이렇게 Checkbox라는 컴포넌트를 만들어서 재활용 해 줄 수 있습니다.
아직 부족한 부분이 많습니다.
혹시나 틀린부분이나 수정할 부분이 있다면 댓글로 알려주시면 감사하겠습니다.