건의사항을 좀더 자세히 만들어 보았습니다.
나중에 db를 사용해서 리팩토링할 수도 있을 것 같지만 일단은 AsyncStorage를 사용해서 작성해보았습니다.
건의사항을 클릭하면 이제까지 등록되었던 건의사항을 리스트로 나열하고, 글작성을 누르면 모달창으로 글 등록창이 뜨게 만들었습니다.
const fetchData = (page) => {
AsyncStorage.getItem("suggestion", (err, result) => {
let Suggestion = JSON.parse(result);
Suggestion = Suggestion.slice(
Suggestion.length - 20 * page,
Suggestion.length
);
Suggestion.sort((a, b) => {
//내림차순 정렬
return a.id > b.id ? -1 : a.id < b.id ? 1 : 0;
});
setNoticeData(Suggestion);
// setPage(page + 1);
});
setRefreshing(false);
};
처음 건의사항을 클릭하면 fetchData를 실행시켜서 20개 * page 수만큼 글의 개수를 불러옵니다.
const renderItem = ({ item }) => {
// const backgroundColor = item.id === selectedId ? "#6e3b6e" : "#f9c2ff";
const backgroundColor = "#FBFCFD";
const color = item.id === selectedId ? "white" : "black";
return (
<Item
item={item}
onPress={() =>
navigation.navigate("suggestScreen", {
data: item,
})
}
backgroundColor={{ backgroundColor }}
textColor={{ color }}
/>
);
};
리스트에서 글을 클릭하면 상세 페이지로 넘어갈 수 있도록 renderItem함수를 작성했습니다.
<FlatList
data={noticeData}
renderItem={renderItem}
//key 값은 문자여야한다.
keyExtractor={(item) => String(item.id)}
extraData={selectedId}
onEndReached={() => {
setPage(page + 1);
fetchData(page);
}}
onEndReachedThreshold={1.1}
refreshing={refreshing}
onRefresh={() => {
setRefresh();
}}
/>
onEndReached로 화면끝에 닿으면 페이지가 추가되어 20개가 늘어난 데이터가 출력되고 onRefresh로 새로고침 하면 setRefresh가 작동하도록 했습니다
const setRefresh = async () => {
AsyncStorage.getItem("suggestion", (err, result) => {
let Suggestion = JSON.parse(result);
Suggestion = Suggestion.slice(Suggestion.length - 20, Suggestion.length);
Suggestion.sort((a, b) => {
//내림차순 정렬
return a.id > b.id ? -1 : a.id < b.id ? 1 : 0;
});
setNoticeData(Suggestion);
});
setRefreshing(false);
};
setRefresh는 다시 20개만 출력하는 함수로 작성했습니다.
그런데 gif를 보면 알 수 있듯이 제가 생각한대로 잘 되지 않습니다. 화면 제일 아래에 도달해도 추가 데이터가 갱신되지 않고, 새로고침을 해도 20개가 아닌 더 많은 데이터가 남아있습니다. 완전 틀린 것 같습니다. 이 부분은 좀 더 코드를 만져봐야할 것 같습니다.
const [modal, setModal] = useState(false);
const WriteButton = () => {
return (
<View>
<Modal animationType="slide" transparent={true} visible={modal}>
<SuggestionScreen setModal={setModal} />
</Modal>
<TouchableOpacity
style={styles.menuButton}
onPress={() => {
setModal(true);
}}
>
<FontAwesome name="edit" color="#EFF0F1" size={20} />
<Text>글 작성</Text>
</TouchableOpacity>
</View>
);
};
기존에 작성했었던 글작성 창인 SuggestionScreen을 모달로 옮기고 setModal을 제어할 수 있도록 props로 내려주었습니다. 기본값은 false이고 글작성 버튼을 누르면 true로 바뀌어 모달창이 활성화가 되도록 설정했습니다.
<TouchableOpacity
//값을 로컬스토리지에 저장한다.
onPress={() => {
if (content) {
AsyncStorage.getItem("suggestion", (err, result) => {
const Suggestion = JSON.parse(result);
AsyncStorage.setItem(
"suggestion",
JSON.stringify(
Suggestion.concat({
id: Suggestion.length + 1,
content: content,
})
)
);
});
alert("글이 등록되었습니다!");
setTimeout(() => {
setModal(false);
}, 1000);
} else {
alert("글을 입력해주세요!");
}
}}
style={{
width: 100,
height: 50,
justifyContent: "center",
alignItems: "center",
// borderRadius: 10,
}}
>
<Text>전송</Text>
</TouchableOpacity>
모달창안에 글을 작성하지 않았다면 alert로 글을 입력하라는 메세지를 남기고 글을 작성했다면 기존의 데이터와 입력한 데이터를 합친 객체를 JSON.stringify로 변환한 후 저장합니다.
<TouchableOpacity
onPress={() => setModal(false)}
style={{
width: 100,
height: 50,
justifyContent: "center",
alignItems: "center",
// borderRadius: 10,
}}
>
<Text>닫기</Text>
</TouchableOpacity>
닫기 버튼도 만들어서 누르면 그냥 setModal(false)로 모달창이 닫기게 설정합니다.
코드를 작성할 수록 점점 컴포넌트 내용들이 뒤죽박죽에 흐트려져가면서 변수명도 이상한게 느껴집니다. 제가 클린한 코드작성을 제대로 하지 않고 있다는 증거인 것 같습니다. 만간 날을 잡아서 컴포넌트 정리를 해야할 것 같습니다.