import {View} from 'react-native';
const DATA_EXAMPLE = [
{
id: 1,
name: "1번"
},
{
id: 2,
name: "2번"
},
];
const Mother = () => {
const [list, setList] = useState();
const [selectList, setSelectList] = useState([])
useEffect(() => {
axios로 데이터를 불러와서 setList에 저장
},[])
const listHandler = (num) => {
if (selectList.includes(num)) {
setSelectList(selectList.filter((el) => el !== num));
} else {
setSelectList([...selectList, num]);
}
};
return(
<View>
{list.map((item) => (
<Son
item={item}
key={item.id}
handler={listHandler}
style = {list.includes(item.id) ? {borderColor: '#2D63E2'} : {borderColor: '#DDDDDD'}}
/>
))
</View>
}
export default Mother
import {Text,Pressable, View} from "react-native"
const Son = ({item, handler, style}) => {
return (
<Pressable style={style} onPress={() => handler(item.id)}>
<View>
<Text>{item.name}</Text>
</View>
</Pressable>
)
}
export default Son
우선 부모 컴포넌트에서 DATA_EXAMPLE
과 같은 데이터를 가진 결과값을 setList
로 넣어준다.
listHandler
함수에서 조건을 추가해 주는데
const listHandler = (num) => {
if (selectList.includes(num)) {
setSelectList(selectList.filter((el) => el !== num));
} else {
setSelectList([...selectList, num]);
}
};
만약에 listHandler 파라미터로 넘어온 num값이 선택된 데이터의 아이디를 저장해 두는 selectList에 있다면
setSelectList로 다시 데이터를 넣어주는데 이때 num값과 같지 않은 데이터들만 남겨주세요.
처음에 실행이 되었을 때는 당연히 selectList의 배열에는 아무것도 존재하지 않기 때문에 else문이 실행이 된다.
그러기 때문에 처음에 클릭한 값은 무조건 배열에 담기게 된다.
따라서 1번 아이템을 클릭하게 되면 selectList는 [1]
이 되는 것이다.
만약에 selectList에 [1]
이 담긴 상태에서 1번 아이템을 클릭하면 if문이 실행이 되어 fileter함수에 의해 제외되고 selectList는 다시 []
빈배열이 된다.
자식 컴포넌트에서
onPress={() => handler(item.id)}
onPress는 리액트에서 onClick과 비슷하다
바로 handler(item.id)로 하지 않은 이유는 부모가 자식에게 함수 자체를 넘겨주어 handler(item.id)를 쓰게 되면 리턴값이 나와야 되는데 리턴값이 없기 때문이다
그렇기에 고차함수를 이용해서 함수 안에서 함수를 실행하도록 조정해주었다.