ํฐ์คํ ๋ฆฌ ๋ทฐ
[NewsFeed-Day 5] data ํํฐ๋งํ๊ธฐ(๊ฒ์์ด ๋ฐ ์นดํ ๊ณ ๋ฆฌ)
์ฑ._. 2025. 2. 17. 04:162025.02.16 (์ผ) Works
1. ๊ฒ์์ด ํํฐ๋ง
1-1. ์ํฐ ๊ฒ์
1-2. join ํด์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
1-3. ๊ฒ์ value ํํฐ๋ง
2. ์ฅ์ ํํฐ๋ง (์ ์ฒด / ๊ตญ๋ด / ๊ตญ์ธ)
2-1. onClick ์ด๋ฒคํธ ์ฃผ๊ธฐ
2-2. ํํฐ๋ง ํจ์ ๋ง๋ค๊ธฐ
๊ฒ์์ด ํํฐ๋ง
์ํฐ ๊ฒ์
๊ฒ์ ํจ์ ๋ด๋ถ์ ์ํฐ๋ก ๊ฒ์ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ค.
๊ฒ์ ํ์๋ ๊ฒ์์ฐฝ์ด ๋น ๊ฐ์ผ๋ก ์ค์ ๋๋ค.
// SearchInput.jsx
const handleSearch = e => {
if (e.key === "Enter") return;
setSearchInput("");
};
join ํด์ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ & ๊ฒ์ value ํํฐ๋ง
๊ฒ์์ด ๋๋ ๊ฐ๋ค์
๊ธ ์ ๋ชฉ, ๋๋ค์, MBTI, ๊ธ ๋ด์ฉ์ผ๋ก ์ ํ๋ค.
๋ฐ๋ผ์ ๋ค ๊ฐ์ ๊ฐ์ ๊ฒ์ ๋ด์ฉ์ด ์๋ ์ง includes๋ก ํ๋ณํ ํ, ํด๋น๋๋ posts(๊ฒ์๊ฐ)์ ๊ทธ๋ ค์ค์ผ ํ๋ค.
์๋ ๋ก์ง์ ์ดํด๋ณด๋ฉด posts(๊ฒ์๊ธ ๋ฐ์ดํฐ)์ filter ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๊ธฐ ๋๋ฌธ์
posts ๋ฐฐ์ด์ ๋๋ค์๊ณผ mbti๊ฐ ํฌํจ๋์ด ์์ด์ผ ํ๋ค.
// SearchInput.jsx
const keyword = searchInput; ๐๐ป ์
๋ ฅ๊ฐ state๋ฅผ 'keyword' ๋ณ์๋ก ์ง์
const searchPosts = posts.filter(post => { ๐๐ป ์ ์ฒด ๊ฒ์๊ธ์์ ๊ฒ์ ๋ด์ฉ์ ํด๋นํ๋ ๊ธ์ filter
return (
post.title.includes(keyword) || ๐๐ป ์ ๋ชฉ ํ๋ณ
post.content.includes(keyword) || ๐๐ป ๋ด์ฉ ํ๋ณ
post.users?.nickname.includes(keyword) || ๐๐ป ๋๋ค์ ํ๋ณ
post.users?.mbti.includes(keyword.toUpperCase()) ๐๐ป mbti ํ๋ณ
);
});
setChangePosts(searchPosts); ๐๐ป ํํฐ๋ง ํ ๊ฐ setState
supabase API ์ค ํ ์ด๋ธ์ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๋ ๋ฐฉ๋ฒ ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ํ ์ด๋ธ์ colomn ๊ฐ์ ํจ๊ป ๊ฐ์ ธ์ฌ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค.
// HomeContext.jsx
supabase.from("posts").select("*, users(nickname, mbti)")
posts์ ๊ฐ์ ์ฝ์์์ ํ์ธํด๋ณด๋ฉด 'users' ์ ๊ฐ๋ ์ ๊ฐ์ ธ์์ก๋ค.

์ฅ์ ํํฐ๋ง (์ ์ฒด / ๊ตญ๋ด / ๊ตญ์ธ)
onClick ์ด๋ฒคํธ ์ฃผ๊ธฐ
์ ์ฒด / ๊ตญ๋ด / ๊ตญ์ธ div์ onClick ์ด๋ฒคํธ๋ฅผ ๋ถ์ฌํ๋ค.
// Home.jsx
return (
<StCategoryContainer>
<StCategory onClick={() => showPosts("all")}>์ ์ฒด</StCategory>
<StCategory onClick={() => showPosts("in")}>๊ตญ๋ด</StCategory>
<StCategory onClick={() => showPosts("out")}>๊ตญ์ธ</StCategory>
</StCategoryContainer>
...
ํํฐ๋ง ํจ์ ๋ง๋ค๊ธฐ
onClick ์ด๋ฒคํธ์ ์ฌ์ฉ๋ ํจ์๋ฅผ ์์ฑํ๋ค.
๐จํธ๋ฌ๋ธ ์ํ 1
ํํฐ๋งํ ๊ฐ์ ๋ ํํฐ๋ง์ด ๋๋ ํ์์ด ๋ฐ๋ณต๋์ด ์ ๋๋ก ์ ๋ ฌ์ด ๋์ง ์์๋ค.
์๋ 1. ์์ ๋ณต์ฌ
tempPosts = [...post]; ๋ก ์์ ๋ณต์ฌ๋ฅผ ํ์ฌ ํํฐ๋ง์ ์ฌ์ฉํ๋ค.
์๋ 2. ๊น์ ๋ณต์ฌ
structuredClone() ์ ์ฌ์ฉํ์ฌ ๊น์ ๋ณต์ฌ์ ๊ฐ์ ํํฐ๋ง์ ์ฌ์ฉํ๋ค.
์๋ 3. card์ ์ง์ ๊ฐ ๋ถ์ฌ
ํํฐ๋งํ ๊ฐ์ card ๋ก์ง์ ์ง์ ๋ฃ์ด์ฃผ์๋ค.
(card ๋ก์ง์ ์นด๋ ํํ๋ฅผ ๊ทธ๋ ค์ฃผ๊ธฐ๋ง ํ๋ฏ๋ก ์๋ชป๋ ์ ๊ทผ์ด๋ค.)
! ๋ฌธ์ ์์ธ : ํํฐ๋งํ ๊ฐ์ setPosts์ ์ฃผ์ด posts์ ๊ฐ ์์ฒด๊ฐ ๋ฐ๋๋ ์ค์ด์๋ค.
โจํด๊ฒฐ ๋ฐฉ๋ฒ
Context์์
const [ changePosts, setChangePosts ] = useState([...posts]);
๋ก ์นด๋ ๋ฆฌ์คํธ๋ฅผ state๋ก ๊ด๋ฆฌํ๋ค.
๐จํธ๋ฌ๋ธ ์ํ 2
์ ๋ ฌ์ ์ ๋์ง๋ง ํ์ด์ง๋ฅผ ์๋ก๊ณ ์นจํ๋ฉด ์นด๋๋ฆฌ์คํธ๊ฐ ๋จ์ง ์์๋ค.
์ฝ์์ ํ์ธํด๋ณด๋ posts์ ๊ฐ์ด ๋น ๋ฐฐ์ด์ด์๋ค๊ฐ ๋ํ๋๋ ๊ฒ์ ํ์ธํ๋ค.
! ๋ฌธ์ ์์ธ : ํ๋ฉด์ด ๋ค ๊ทธ๋ ค์ง๊ณ ๋ ํ, DB์์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ค๊ธฐ ๋๋ฌธ์ ๋ค๋ฆ๊ฒ ๊ฐ์ด ๋ฐ์๋๋ ๊ฒ์ด๋ค.
โจํด๊ฒฐ ๋ฐฉ๋ฒ
useEffect ๋ฅผ ์ฌ์ฉํ์ฌ posts์ ๊ฐ์ด ๋ณํ ๋, useEffect๊ฐ ํ ๋ฒ ๋ ์คํ๋๋ค.
๋ฐ๋ผ์ ์์กด์ฑ ๋ฐฐ์ด์๋ ๋ณํ๋ ๊ธฐ์ค์ ๊ฐ์ ๋ฃ์ด์ฃผ๊ณ , ํจ์ ๋ด๋ถ์๋ ์คํํ ๋ก์ง์ ์์ฑํ๋ค.
useEffect(() => {
setChangePosts(posts);
}, [posts]);
์ต์ข ๋ก์ง
styled-commponents ์๋ต
// Home.jsx
...
useEffect(() => {
setChangePosts(posts);
}, [posts]);
const showPosts = where => {
if (where === "all") {
setChangePosts([...posts]);
return;
}
if (where === "in") {
const filterInPost = posts.filter(post => {
return post.travel_location === "๊ตญ๋ด";
});
setChangePosts(filterInPost);
return;
}
if (where === "out") {
const filterOutPost = posts.filter(post => {
return post.travel_location === "๊ตญ์ธ";
});
setChangePosts(filterOutPost);
return;
}
};
const showModal = post => {
setSelectedPost(post);
};
return (
<>
<StCategoryContainer>
<StCategory onClick={() => showPosts("all")}>์ ์ฒด</StCategory>
<StCategory onClick={() => showPosts("in")}>๊ตญ๋ด</StCategory>
<StCategory onClick={() => showPosts("out")}>๊ตญ์ธ</StCategory>
</StCategoryContainer>
<div>
{changePosts.map((post, index) => {
return (
<MoveModal
key={`${post.uid}-${index}`}
onClick={e => {
if (e.target.classList.contains("heart")) {
return;
}
showModal(post);
}}
>
<HomePostCard post={post} />
</MoveModal>
);
})}
</div>
{isSignin === true ? <AddPostButton /> : null}
{selectedPost && (
<ShowModal
post={selectedPost}
closeModal={() => setSelectedPost(null)}
/>
)}
</>
);
};
export default Home;'Forntend > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| supabase์ ๋ฐ์ดํฐ ์ฟผ๋ฆฌ ์ฒ๋ฆฌ ๋ฐฉ์ - await ํ์ ! (0) | 2025.03.10 |
|---|---|
| [NewsFeed-Day 4] Modal ์ฐ๊ฒฐ (0) | 2025.02.15 |
| [NewsFeed-Day 3] supabase ๋ฐ์ดํฐ ๋๊ธฐํ (1) | 2025.02.15 |
| [NewsFeed-Day 2] supabase ๊ฐ ์ก๊ธฐ (0) | 2025.02.14 |
| ๊ตฌ์กฐ๋ถํดํ ๋น (Context ์ฌ์ฉ ์์) (0) | 2025.02.10 |