๐ฅขRedux์ ์ ํ๊ธฐ
A โselectorโ is simply a function that accepts Redux state as an argument and returns data that is derived from that state.
A selector is a small function you write that can take the entire Redux state, and pick out a value from it.
mapStateToProps
๊ฐ ์ด๋ป๊ฒ ์๋ํ๋์ง ์์ญ๋๊น? ์ ์ฒด ์ํ๋ฅผ ๊ฐ์ ธ์์ ๊ฐ์ ์ ํํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์
๋๊น? ์ ํ์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ทธ๋ ๊ฒ ํฉ๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋ณด๋์ค๋ก ์ํ๊ฐ ๋ณ๊ฒฝ๋ ๋๊น์ง ๊ฐ์ ์บ์ฑํ์ฌ ์ฑ๋ฅ๋ ํฅ์๋ฉ๋๋ค. ์ โ ์ฑ๋ฅ์ ํฅ์์ํฌ ์ ์์ต๋๋ค.์ ํ์๋ฅผ ์ฌ์ฉํด์ผ ํ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น?
Redux ์ ์ฅ์ ์ํ๋ฅผ ์ต์ํํ๊ณ ํ์์ ๋ฐ๋ผ ์ํ์์ ๋ฐ์ดํฐ๋ฅผ ํ์์ํค๋ ๊ฒ์ด ๊ฐ์ฅ ์ข์ต๋๋ค. ์ ํ์๋ ์ด๋ฅผ ๋์์ค๋๋ค. ๊ทธ๋ค์ ํ์๋ ๋ฐ์ดํฐ๋ฅผ ๊ณ์ฐํ ์ ์์ด Redux๊ฐ ๊ฐ๋ฅํ ์ต์ํ์ ์ํ๋ฅผ ์ ์ฅํ ์ ์์ต๋๋ค. ์ ํ์๋ ๋งค์ฐ ํจ์จ์ ์ ๋๋ค. ์ ํ์๋ ์ธ์ ์ค ํ๋๊ฐ ๋ณ๊ฒฝ๋์ง ์๋ ํ ๋ค์ ๊ณ์ฐ๋์ง ์์ต๋๋ค.
์ ํ๊ธฐ์ ๋ช ๊ฐ์ง ์:
๊ธฐ์ด์ ์ธ :
selectUsers = state => state.users;
ID๋ฅผ ์ฌ์ฉํ์ฌ ์ฝ๊ฐ ๋ณต์กํจ:
selectUserIds = state => state.users.map(user => user.id);
๋ ๋ณต์กํ:
selectUserIdsOfName = (state, name) => state.users.filter(user => user.name === name);
์
Redux๋ ์ํ๋ฅผ ์ ์ฅํ ์ ์๋ ์ ์ฅ์๋ฅผ ์ ๊ณตํฉ๋๋ค. ๋ ํฐ ์ฑ์์ ํด๋น ์ํ๋ ์ผ๋ฐ์ ์ผ๋ก ๊ฐ์ฒด์ ๊ฐ ํค๊ฐ ๋ณ๋์ ๊ฐ์๊ธฐ์ ์ํด ๊ด๋ฆฌ๋๋ ๊ฐ์ฒด์ ๋๋ค.
{
currentUser: {
token,
userId,
username
},
shoppingCart: {
itemIds,
loading,
error
},
products: {
itemsById,
loading,
error
}
}
์ฒซ์งธ, ์ ํ์ ์์ด
mapStateToProps
ํจ์๋ฅผ ์์ฑํฉ๋๋ค. function mapStateToProps(state) {
return {
items: state.shoppingCart.itemIds.map(id =>
state.products.itemsById[id]
)
}
}
์ํ ๋ชจ์์ ๋ณ๊ฒฝํ๋ฉด mapStateToProps๊ฐ ์ค๋จ๋ฉ๋๋ค.
์ด์ โ "์๋ค์ํผ...
shoppingCart
๋ ๋
๋ฆฝ ์คํํ์ด ์๋ currentUser
์ ์์ฑ์ด์ด์ผ ํฉ๋๋ค."๋ผ๊ณ ๊ฒฐ์ ํ๋ฉด ์ด๋ป๊ฒ ๋ฉ๋๊น? ๊ทธ๋ฐ ๋ค์ ์ํ๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ฌ๊ตฌ์ฑํฉ๋๋ค.currentUser: {
token,
userId,
username,
shoppingCart: {
itemIds,
loading,
error
},
},
products: {
itemsById,
loading,
error
}
}
mapStateToProps
๊ธฐ๋ฅ์ด ์์๋์์ต๋๋ค. ํ์ฌ state.shoppingCart
์ ์๋ state.currentUser.shoppingCart
๋ฅผ ์ฐธ์กฐํฉ๋๋ค. state.shoppingCart
๋ฅผ ์ฐธ์กฐํ๋ ์ฌ๋ฌ ์์น๊ฐ ์๋ ๊ฒฝ์ฐ ๋ชจ๋ ์์น๋ฅผ ์
๋ฐ์ดํธํ๋ ๊ฒ์ ๊ณ ํต์ค๋ฌ์ธ ๊ฒ์
๋๋ค. ์ฑ๊ฐ์ ์
๋ฐ์ดํธ ํ๋ก์ธ์ค์ ๋ํ ๋๋ ค์์ด๋ ํํผ๊ฐ ์ํ๋ฅผ ์ฌ๊ตฌ์ฑํด์ผ ํจ์ ์๋ฉด์๋ ์ํ๋ฅผ ์ฌ๊ตฌ์ฑํ์ง ๋ชปํ๊ฒ ํ ์๋ ์์ต๋๋ค. ์ํ์ ๋ชจ์์ ๋ํ ์ง์์ ์ค์ ์ง์คํํ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉดโฆ ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ์ฐพ๋ ๋ฐฉ๋ฒ์ ์๊ณ ์๋ ์ผ์ข ์ ํจ์๋ผ๊ณ ๋ถ๋ฅผ ์ ์์ต๋๋ค.
๊ธ์, ๊ทธ๊ฒ์ด ๋ฐ๋ก ์ ํ๊ธฐ์ ์ฉ๋์ ๋๋ค :)
๋ฆฌํฉํ ๋ง: ๊ฐ๋จํ ์ ํ๊ธฐ ์์ฑ
๊นจ์ง
mapStateToProps
์ ๋ค์ ์์ฑํ๊ณ ์ํ ์ก์ธ์ค๋ฅผ ์ ํ๊ธฐ๋ก ๊ฐ์ ธ์ต๋๋ค.// put this in some global-ish place,
// like selectors.js,
// and import it when you need to access this bit of state
function selectShoppingCartItems(state) {
return state.currentUser.shoppingCart.itemIds.map(id =>
state.products.itemsById[id]
);
}
function mapStateToProps(state) {
return {
items: selectShoppingCartItems(state)
}
}
๋ค์์ ์ํ ๋ชจ์์ด ๋ณ๊ฒฝ๋๋ฉด ํ๋์ ์ ํ๊ธฐ๋ฅผ ์ ๋ฐ์ดํธํ๋ฉด ์๋ฃ๋ฉ๋๋ค.
๋ฉ๋ชจ์ด์ ์ด์
๊ฒฐ๋ก
์ ํ๊ธฐ๋ Redux ์ํ๋ฅผ ์ธ์๋ก ๋ฐ์๋ค์ด๊ณ ํด๋น ์ํ์์ ํ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ฐํํ๋ ํจ์์ ๋๋ค. ์ ํ๊ธฐ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฑ๋ฅ ์ต์ ํ๋ฅผ ์ ๊ณตํ๊ณ ์ ์ญ ์ํ ํธ๋ฆฌ๋ฅผ ์บก์ํํ๋ ๋ฐ ๋์์ด ๋ ์๋ ์์ต๋๋ค.
Reference
์ด ๋ฌธ์ ์ ๊ดํ์ฌ(๐ฅขRedux์ ์ ํ๊ธฐ), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://dev.to/nawazmujawar/selector-in-redux-4ebaํ ์คํธ๋ฅผ ์์ ๋กญ๊ฒ ๊ณต์ ํ๊ฑฐ๋ ๋ณต์ฌํ ์ ์์ต๋๋ค.ํ์ง๋ง ์ด ๋ฌธ์์ URL์ ์ฐธ์กฐ URL๋ก ๋จ๊ฒจ ๋์ญ์์ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ ์ธ ๋ฐ๊ฒฌ์ ์ ๋ (Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค