리스트의 아이템 more버튼을 클릭하면 새로운 기능 박스가 나오는 상황이다. 다른 아이템을 누르면 기존 box가 사라지고 한번 더 누르면 toggle되는 기능을 react로 구현해보았다.
// TodoList.jsx
const TodoList = ({ todoReducer }) => {
return (
<Styled.ListContainer>
{todoReducer.map((list, index) => {
return (
<TodoItem
key={list.id}
todoItem={list}
currentNumber={index + 1}
/>
);
})}
</Styled.ListContainer>
);
};
//TodoItem.jsx
const TodoItem = ({
todoItem,
currentNumber,
}) => {
return (
<Styled.ListContainer>
<Styled.Left done={todoItem.done}>
<Styled.Content>
{currentNumber}. {todoItem.content}
</Styled.Content>
<Styled.Date>{todoItem.dates}</Styled.Date>
</Styled.Left>
<Styled.More />
<MoreBox todoItem={todoItem} />
</Styled.ListContainer>
);
};
//MoreBox.jsx
const MoreBox = ({ todoItem }) => {
return (
<Styled.Box>
<Styled.ListBox>
<Styled.Text>Delete</Styled.Text>
<Styled.Delete />
</Styled.ListBox>
<Styled.ListBox>
<Styled.Text>Done</Styled.Text>
<Styled.Done />
</Styled.ListBox>
</Styled.Box>
);
};
list => item => box 순으로 컴포넌트를 분리해서 만들어보았다.
//TodoList.jsx
const TodoList = ({ todoReducer }) => {
const [currentIndex, setCurrentIndex] = useState(-1);
return (
<Styled.ListContainer>
{todoReducer.map((list, index) => {
return (
<TodoItem
key={list.id}
todoItem={list}
currentNumber={index + 1}
isShow={index === currentIndex ? true : false}
index={index}
setCurrentIndex={setCurrentIndex}
/>
);
})}
</Styled.ListContainer>
);
};
클릭한 아이템을 비교하고 결과를 boolean으로 내보내주기 위하여 isShow라는 props로 비교한 결과를 보내주는 코드를 작성하였다.
또한 값이 변할때 리렌더링이 되어야 하기 때문에 useState로 currentIndex를 구성하였다.
//TodoItem.jsx
const TodoItem = ({
todoItem,
currentNumber,
index,
isShow,
setCurrentIndex,
}) => {
const onMoreButtonClick = (index) => {
setCurrentIndex(index);
};
return (
<Styled.ListContainer>
<Styled.Left done={todoItem.done}>
<Styled.Content>
{currentNumber}. {todoItem.content}
</Styled.Content>
<Styled.Date>{todoItem.dates}</Styled.Date>
</Styled.Left>
<Styled.More onClick={(e) => onMoreButtonClick(e, index)} />
<MoreBox todoItem={todoItem} isShow={isShow} />
</Styled.ListContainer>
);
};
클릭시 currentIndex를 변경하여 isShow의 boolean값을 변경해주는 함수이다.
//MoreBox.jsx
const MoreBox = ({ todoItem, isShow }) => {
return (
<Styled.Box isShow={isShow}>
<Styled.ListBox>
<Styled.Text>Delete</Styled.Text>
<Styled.Delete />
</Styled.ListBox>
<Styled.ListBox>
<Styled.Text>Done</Styled.Text>
<Styled.Done />
</Styled.ListBox>
</Styled.Box>
);
};
MoreBox는 isShow의 값을 받아서 true일경우 display:block이고 false일경우 none으로 style을 주었다.
그러나 현재 아이템을 클릭하고 다른 아이템을 클릭할때는 기존아이템의 MoreBox가 사라지는데 한번더 눌렀을때 토글기능이 되지 않는다.
//TodoItem.jsx
const TodoItem = ({
todoItem,
currentNumber,
index,
isShow,
setCurrentIndex,
}) => {
const onMoreButtonClick = (e, index, isShow) => {
if (isShow) {
setCurrentIndex(-1);
} else {
setCurrentIndex(index);
}
};
return (
<Styled.ListContainer>
<Styled.Left done={todoItem.done}>
<Styled.Content>
{currentNumber}. {todoItem.content}
</Styled.Content>
<Styled.Date>{todoItem.dates}</Styled.Date>
</Styled.Left>
<Styled.More onClick={(e) => onMoreButtonClick(e, index, isShow)} />
<MoreBox todoItem={todoItem} isShow={isShow} />
</Styled.ListContainer>
);
};
onClick함수만 살짝 바꿔주었다. isShow가 true일때는 -1을 넣어서 다시 false가 되게하고 반대일 경우 기존과 똑같이 적용하는것이다.