๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

React

[React] ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ง›๋ณด๊ธฐ

์ƒํƒœ(state)๋ž€ UI์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์œ ์ง€ํ•ด์•ผํ•  ๊ฐ’์ด๋‹ค. ๋ฆฌ์•กํŠธ์—์„œ๋Š” ์ปดํฌ๋„ŒํŠธ์— ์ €์žฅํ•œ ๋ฐ์ดํ„ฐ(์ƒํƒœ)๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๊ทธ์— ๋”ฐ๋ผ UI๊ฐ€ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฆฌ์•กํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ƒํƒœ๊ฐ’์„ ํšจ์œจ์ ์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ณ  ์ƒํƒœ๊ฐ’์— ๋”ฐ๋ผ ํ™”๋ฉด์ด ๋ถˆํ•„์š”ํ•˜๊ฒŒ ์—…๋ฐ์ดํŠธ๋˜์ง€ ์•Š๋„๋ก ์ฃผ์˜ํ•ด์•ผ ํ•œ๋‹ค.

 

 

์ƒํƒœ๋Š” ๋‘๊ฐ€์ง€๋กœ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ ์ง€์—ญ์ƒํƒœ์™€ ์ „์—ญ์ƒํƒœ์ด๋‹ค. ์ง€์—ญ์ƒํƒœ์˜ ๊ฒฝ์šฐ useState๊ฐ™์ด ์ปดํฌ๋„ŒํŠธ ๋‚ด์—์„œ ํ›…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์œ„ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ ๋ฆฌ์•กํŠธ๋Š” ๋‹จ๋ฐฉํ–ฅ์˜ ํŠน์„ฑ์„ ์ง€๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ƒํƒœ๋ฅผ ์ „๋‹ฌํ•  ์ˆ˜ ์—†๊ณ , props๋กœ ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์—ญ์ƒํƒœ๋Š” ์–ด๋–ค ํ๋ฆ„์— ์–ฝ๋ฉ”์ด์ง€ ์•Š๊ณ  ์ „์—ญ์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋ฅผ ๋งํ•œ๋‹ค.

 

ํ•˜๋‚˜์˜ ์ƒํƒœ๋ฅผ ์—ฌ๋Ÿฌ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ ์–ด๋–ป๊ฒŒ๋“  ์ƒ์œ„์˜ ์ปดํฌ๋„ŒํŠธ์—์„œ props๋กœ ์ „๋‹ฌํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ props์˜ ์ „๋‹ฌ์ด ๋งŽ์•„์งˆ์ˆ˜๋ก ์ฝ”๋“œ๋ฅผ ์ฝ์„ ๋•Œ ํ•ด๋‹น prop์„ ์ถ”์ ํ•˜๊ธฐ ํž˜๋“ค์–ด์ง€๊ณ  ๊ทธ์— ๋”ฐ๋ผ ์œ ์ง€๋ณด์ˆ˜๋„ ๋”์šฑ ์–ด๋ ค์›Œ์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ๋ฅผ ํ•  ํ•„์š”๊ฐ€ ์žˆ๋‹ค.

 

 

 

๐ŸŒ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋„๊ตฌ

๐Ÿ“˜ Context API

์ „์—ญ ์ƒํƒœ๋ฅผ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฆฌ์•กํŠธ์—์„œ ๋งŒ๋“ค์—ˆ๋‹ค. ํŠธ๋ฆฌ ๋‹จ๊ณ„๋งˆ๋‹ค ๋ช…์‹œ์ ์œผ๋กœ props๋ฅผ ๋„˜๊ฒจ์ฃผ์ง€ ์•Š์•„๋„ ๋งŽ์€ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๊ฐ’์„ ๊ณต์œ ํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Context API๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Context, Provider, Consumer ์„ธ ๊ฐ€์ง€๋ฅผ ์ˆ™์ง€ํ•ด์•ผ ํ•œ๋‹ค.

Context
์ „์—ญ ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ์—ญํ• 
Context ๋‚ด๋ถ€์— Provider์™€ Consumer๊ฐ€ ์ •์˜๋˜์–ด์žˆ๊ณ , Consumer๋Š” Context๋ฅผ ํ†ตํ•ด์„œ ์ƒํƒœ์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. 

Provider
์ „์—ญ ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๋Š” ์—ญํ• 
Context์— ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•ด์„œ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค€๋‹ค. ์ œ๊ณต๋œ ์ƒํƒœ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Provider ํ•˜์œ„์— ์ปดํฌ๋„ŒํŠธ๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ์–ด์•ผํ•œ๋‹ค. ๋ณดํ†ต ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ทผํ•ด์•ผํ•˜๋Š” ์ƒํƒœ๋ฅผ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ฃจํŠธ ์ปดํฌ๋„ŒํŠธ์—์„œ Provider๋ฅผ ์ •์˜ํ•œ๋‹ค.

Consumer
์ œ๊ณต๋ฐ›์€ ์ „์—ญ ์ƒํƒœ๋ฅผ ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋Š” ์—ญํ• 
Context๋Š” Consumer ์‚ฌ์ด์— ์žˆ๋Š” ์ฒซ ๊ฐ์ฒด๋ฅผ Context์— ์ธ์ž๋กœ ์ „๋‹ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋ฐ”๋กœ JSX๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ์•ˆ๋˜๊ณ , ๋นˆ ๊ฐ์ฒด๋ฅผ ์ž‘์„ฑํ•˜๊ณ ๋‚˜์„œ JSX๋ฅผ ์ž‘์„ฑํ•ด์•ผํ•œ๋‹ค.

 

 

const MyContext = React.createContext(defaultValue);
// defaultValue ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ํŠธ๋ฆฌ ์•ˆ์—์„œ ์ ์ ˆํ•œ Provider๋ฅผ ์ฐพ์ง€ ๋ชปํ–ˆ์„ ๋•Œ๋งŒ ์“ฐ์ด๋Š” ๊ฐ’

const [value, setValue] = useState(์ดˆ๊ธฐ๊ฐ’)

return (
  <MyContext.Provider value={{value, setValue}}>
  	<ํ•˜์œ„ ์ปดํฌ๋„ŒํŠธ />
    ...
  </MyContext>
)
return(
  <ThemeContext.Consumer>
    {value => <span>{value}</span>}
  </ThemeContext.Consumer>
)

 

useContext hook์„ ์‚ฌ์šฉํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

const {value, setValue} = useContext(MyContext);

return (
  <div>
    <span>{value}</span>
  </div>
);

 

๐Ÿ˜€ ์žฅ์ 

  • React์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ณ„๋„ ์„ค์น˜ ํ•„์š”ํ•˜์ง€ ์•Š๋‹ค.

๐Ÿฅฒ ๋‹จ์ 

  • ์ปจํ…์ŠคํŠธ๊ฐ€ ๋‘˜๋Ÿฌ์‹ผ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋ฆฌ๋žœ๋”๋ง๋œ๋‹ค. (memo ์‚ฌ์šฉ์œผ๋กœ ๋ฐฉ์ง€ ๊ฐ€๋Šฅ)

 

๐Ÿ“• Redux

Flux ํŒจํ„ด์„ ์ ์šฉํ•œ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

 

Store ์— ์ƒํƒœ๋“ค์„ ์ €์žฅํ•˜๊ณ , ํ•ด๋‹น ์–ด๋– ํ•œ ๋ณ€ํ™”๊ฐ€ ํ•„์š”ํ•  ๋•Œ Action ์„ Dispatch ํ•˜์—ฌ Reducer ์—์„œ ์ด๋ฅผ ๋ฐ›์•„ ์ •ํ•ด๋†“์€ ํ๋ฆ„์œผ๋กœ ์ƒํƒœ๋ฅผ ๋ณ€ํ™”์‹œํ‚ค๋Š” ๋ฐฉ์‹

Redux์˜ 3์›์น™

1. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ์ƒํƒœ๋Š” ํ•˜๋‚˜์˜ ์Šคํ† ์–ด ์•ˆ์— ํ•˜๋‚˜์˜ ๊ฐ์ฒด ํŠธ๋ฆฌ ๊ตฌ์กฐ๋กœ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
2. ์ƒํƒœ๋Š” ๋ถˆ๋ณ€(์ฝ๊ธฐ ์ „์šฉ) ๋ฐ์ดํ„ฐ ์ด๋ฉฐ, ์˜ค์ง ์•ก์…˜ ๋งŒ์ด ์ƒํƒœ ๊ต์ฒด๋ฅผ ์š”์ฒญ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
3. ์•ก์…˜์— ์˜ํ•ด ์ƒํƒœ ํŠธ๋ฆฌ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€ํ™”ํ•˜๋Š” ์ง€๋ฅผ ์ง€์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ˆœ์ˆ˜ ๋ฆฌ๋“€์„œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

 

Store
์ „์—ญ์ƒํƒœ๋ฅผ ์ €์žฅํ•œ๋‹ค.
์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด ํ˜•ํƒœ๋กœ ์ €์žฅ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์˜ค์ง Reducer๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. Store๋Š” 1๊ฐœ๋งŒ ์กด์žฌํ•  ์ˆ˜ ์žˆ๋‹ค. 
 
Action
Reducer์—๊ฒŒ ๋ณด๋‚ด๋Š” Store์— ๋Œ€ํ•œ ํ–‰๋™์„ ์ •์˜ํ•œ๋‹ค.
Action์„ Reducer์—๊ฒŒ ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” dispatch ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค. dispatch๋Š” Store์˜ ๋‚ด์žฅ ํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜๋กœ ์•ก์…˜ ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ค˜์„œ ์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ๋‹ค. ์ด๋ฒคํŠธ๋ฅผ ์ผ์–ด๋‚˜๊ฒŒํ•˜๋Š” ์ด๋ฒคํŠธ ํŠธ๋ฆฌ๊ฑฐ์˜ ์—ญํ• ์„ ํ•œ๋‹ค. 
 
Reducer
์ด์ „ ์ƒํƒœ์™€ ์•ก์…˜์„ ๋ฐ›์•„, ๋‹ค์Œ ์ƒํƒœ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์—ญํ• 
Reducer๋ฅผ ํ†ตํ•ด์„œ๋งŒ ์ „์—ญ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ๋‹ค. ์–ด๋–ค ์•ก์…˜์ด ๋“ค์–ด์˜ค๋Š”์ง€ ๊ทธ ์œ ํ˜•์— ๋”ฐ๋ผ ์ด๋ฒคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์ด๋ฒคํŠธ ๋ฆฌ์Šค๋„ˆ๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด์ „ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๋Š” ์ ์ด ์•„๋‹ˆ๋ผ ์ƒˆ๋กœ์šด ์ƒํƒœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์„œ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค.

dispatch 
action์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ
์ƒํƒœ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ์œ ์ผํ•œ ๋ฐฉ๋ฒ•์€ store.dispatch() ๋ฉ”์„œ๋“œ๋ฅผ ๋ถ€๋ฅด๊ณ  action ๊ฐ์ฒด๋ฅผ ๋„˜๊ฒจ์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

 

redux ๊ณต์‹ ๋ฌธ์„œ์˜ ๊ทธ๋ฆผ

 

๐Ÿ˜€ ์žฅ์ 

  • ์™ธ๋ถ€์—์„œ ๊ด€๋ฆฌ Context API์ฒ˜๋Ÿผ ๋ฆฌ๋žœ๋”๋ง x

๐Ÿฅฒ ๋‹จ์ 

  • ๋ฆฌ๋•์Šค ์Šคํ† ์–ด ํ™˜๊ฒฝ ์„ค์ •์˜ ๋ณต์žก์„ฑ
  • ๋ฆฌ๋•์Šค๋ฅผ ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋ถ™๋Š” ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฏธ๋“ค์›จ์–ด
  • ๋ณด์ผ๋Ÿฌํ”Œ๋ ˆ์ดํŠธ, ์ฆ‰ ์–ด๋–ค ์ผ์„ ํ•˜๊ธฐ ์œ„ํ•ด ๊ผญ ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” (์ƒ์šฉ๊ตฌ)์ฝ”๋“œ๊ฐ€ ๋งŽ์ด ์š”๊ตฌ๋œ๋‹ค.
  • ์„ค๊ณ„ ์ฒ ํ•™์— ์š”๊ตฌ๋˜๋Š” ์ฝ”๋”ฉ ๋ฐฉ์‹์„ ๊ผญ ์ถ”๊ตฌํ•ด์•ผํ•ด์„œ ์˜คํžˆ๋ ค ์ฝ”๋“œ๊ฐ€ ๋ณต์žกํ•ด์งˆ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ“— Recoil

Context API ๊ธฐ๋ฐ˜์œผ๋กœ ํŽ˜์ด์Šค๋ถ์—์„œ ๋งŒ๋“  ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

 

Recoil ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ƒ์œ„ ์ปดํฌ๋„ŒํŠธ(App ๋˜๋Š” Router)๋ฅผ RecilRoot ๋ฅผ ํ†ตํ•ด์„œ ๊ฐ์‹ธ์ค˜์•ผ ํ•œ๋‹ค.

function App() {
  return (
    <RecoilRoot>
      <Router />
    </RecoilRoot>
  );
}

 

Atoms๋Š” ์ƒํƒœ์˜ ๋‹จ์œ„์ด๋ฉฐ, ์—…๋ฐ์ดํŠธ์™€ ๊ตฌ๋…์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

๊ณ ์œ ๊ฐ’์ธ key๋ฅผ ์„ค์ •ํ•ด์ฃผ๊ณ  default์— ๊ธฐ๋ณธ๊ฐ’์„ ํ• ๋‹นํ•ด์ค€๋‹ค.

 

export const userState = atom<userProps>({
  key: `userState/${v1()}`,
  default: {
    id: '',
    nickname: '',
    hair: '',
  },
});
const [user, setUser] = useRecoilState(userState);

 

Selector๋Š” atoms๋‚˜ ๋‹ค๋ฅธ selectors๋ฅผ ์ž…๋ ฅ์œผ๋กœ ๋ฐ›์•„๋“ค์ด๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜(pure function)๋‹ค.

์ƒํƒœ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋Š” ํŒŒ์ƒ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณ„์‚ฐํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. ์ตœ์†Œํ•œ์˜ ์ƒํƒœ ์ง‘ํ•ฉ๋งŒ atoms์— ์ €์žฅํ•˜๊ณ  ๋‹ค๋ฅธ ๋ชจ๋“  ํŒŒ์ƒ๋˜๋Š” ๋ฐ์ดํ„ฐ๋Š” selectors์— ๋ช…์‹œํ•œ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํšจ์œจ์ ์œผ๋กœ ๊ณ„์‚ฐํ•จ์œผ๋กœ์จ ์“ธ๋ชจ์—†๋Š” ์ƒํƒœ์˜ ๋ณด์กด์„ ๋ฐฉ์ง€ํ•œ๋‹ค.(https://recoiljs.org/ko/docs/introduction/core-concepts/)

 

const showUserState = selector({
  key: 'showUserState',
  get: ({get}) => {
    const {id, nickname, hair} = get(userState);
    return `
      id: ${id}
      nickname: ${nickname}
      hair: ${hair}
    `;
  },
});

 

์žฅ์ 

  • ๋Ÿฌ๋‹์ปค๋ธŒ๊ฐ€ ์ž‘๋‹ค.
  • ๋น„๋™๊ธฐ ์ฒ˜๋ฆฌ๊ฐ€ ๋‚ด์žฅ๋˜์–ด ์žˆ๋‹ค.

๋‹จ์ 

  • ํ•จ์ˆ˜ํ˜• ์ปดํฌ๋„ŒํŠธ์—์„œ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅ

 

 

๐Ÿ“™ Zustand

fluxํŒจํ„ด์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๊ฐœ์˜ ์ค‘์•™์— ์ง‘์ค‘๋œ ํ˜•์‹์˜ ์Šคํ† ์–ด ๊ตฌ์กฐ๋ฅผ ํ™œ์šฉํ•œ๋‹ค.

// store.js
import create from 'zustand' // create๋กœ zustand๋ฅผ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค.

const useStore = create(set => ({
  count: 0,
  increase: () => set(state => ({ count: state.count + 1 })),
  resetCount: () => set({ count: 0 })
}))

export default useStore
import useStore from '../store.js'

const { count, increase, resetCount } = useStore(state => state)

 

์žฅ์ 

  • Context API๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๋‹ฌ๋ฆฌ ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋žœ๋”๋ง์„ ์ผ์œผํ‚ค์ง€ ์•Š๋„๋ก ์ œ์–ดํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋žœ๋”๋ง์„ ์ผ์œผํ‚ค์ง€ ์•Š๋„๋ก ์ œ์–ดํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • ๋Ÿฌ๋‹์ปค๋ธŒ๊ฐ€ ์ž‘๋‹ค.

๋‹จ์ 

  • ๋‹จ์ ์„ ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค..

 

๐Ÿ“’ jotai

atomic ํŒจํ„ด์œผ๋กœ ํ•œ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.

import { atom } from 'jotai'

const countAtom = atom(0);
const mangaAtom = atom({ 'label': '', 'content': '' });
const [count, setCount] = useAtom(countAtom)

3๊ฐ€์ง€์˜ atom ํ˜•ํƒœ

  • ์ฝ๊ธฐ ์ „์šฉ atom
  • ์“ฐ๊ธฐ ์ „์šฉ atom
  • ์ฝ๊ธฐ-์“ฐ๊ธฐ atom
const readOnlyAtom = atom((get) => get(priceAtom) * 2);

const writeOnlyAtom = atom(
  null, //  ์ฒซ ๋ฒˆ์งธ ์ธ์ˆ˜์— 'null'์„ ์ „๋‹ฌํ•˜๋Š” ๊ทœ์น™์ž…๋‹ˆ๋‹ค.
  (get, set, update) => {
    // update๋Š” atom์„ ์—…๋ฐ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ›์•„์˜ค๋Š” ๊ฐ’์ž…๋‹ˆ๋‹ค.
    set(priceAtom, get(priceAtom) - update.discount)
  }
);

const readWriteAtom = atom(
  (get) => get(priceAtom) * 2,
  (get, set, newPrice) => {
    set(priceAtom, newPrice / 2)
    // ๋™์‹œ์— ์›ํ•˜๋Š” ๋งŒํผ atom์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  }
);

 

์ถ”๊ฐ€์ ์œผ๋กœ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์žฅ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ์ผ๋ถ€ ๊ฐœ๋ฐœ์ž๋“ค ์‚ฌ์ด์—์„œ Recoil๋ณด๋‹ค ์„ ํ˜ธ๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค๊ณ  ํ•œ๋‹ค.

  • ๊ฒฝ๋ž‘ํ™”๋œ API (Minimalistic API)
  • String key์˜ ๋ฏธ์‚ฌ์šฉ
  • ํƒ€์ž…์Šคํฌ๋ฆฝํŠธ ๊ธฐ๋ฐ˜
  • utils ํ•จ์ˆ˜๋“ค์˜ ์ œ๊ณต

 

 

 

jotai๋Š” ์•„์ง ์‚ฌ์šฉํ•ด๋ณด์ง€ ์•Š์•˜๋Š”๋ฐ ๋‹ค์Œ ํ”„๋กœ์ ํŠธ์—์„œ ํ•œ ๋ฒˆ ์‚ฌ์šฉํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค. Redux๋ฅผ ์ฒ˜์Œ ์‚ฌ์šฉํ•ด๋ณด์•˜์„ ๋•Œ ์ƒ๊ฐ๋ณด๋‹ค ๋ณต์žกํ•ด์„œ ์–ด๋ ค์›€์ด ์žˆ์—ˆ๋Š”๋ฐ Recoil, Zustand๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐœ์ธ์ ์œผ๋กœ ๋„ˆ๋ฌด ์‹ ์„ธ๊ณ„์˜€๋‹ค. ์ ์  ๋งŽ์€ ์ „์—ญ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋“ค์ด ๋‚˜์˜ค๋Š”๋ฐ ์ ์  ๊ฐ„์†Œํ™”๋˜๊ณ  ์‚ฌ์šฉ๋ฐฉ๋ฒ•์ด ํŽธํ•ด์ง€๋Š” ๊ฒƒ ๊ฐ™๋‹ค. Recoil์„ ์‚ฌ์šฉํ–ˆ๋˜ ํ”„๋กœ์ ํŠธ์—์„œ ๊ณค๋ž€ํ•œ ์ ์ด ์žˆ์—ˆ๋Š”๋ฐ ํด๋ž˜์Šค ๋‚ด์—์„œ ์ „์—ญ์ƒํƒœ๋ฅผ ๋ฐ›์•„๋ณด๋ ค๊ณ  ํ–ˆ์„ ๋•Œ์˜€๋‹ค. ํ”„๋กœ์ ํŠธ ํ›„๋ฐ˜๋ถ€๋ผ ๋ฐ”๊พธ์ง€ ๋ชปํ•˜๊ณ  emitter๋ฅผ ํ†ตํ•ด ์šฐํšŒํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ–ˆ์—ˆ๋Š”๋ฐ, ๋‹ค์–‘ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด๋ณด๊ณ  ์ƒํ™ฉ์— ๋งž๋Š” ๊ธฐ์ˆ  ์Šคํƒ ์„ ์ •์„ ํ•ด์•ผ๊ฒ ๋‹ค!

 

๐Ÿ“š ์ฐธ๊ณ 

https://naon.me/posts/til104

 

๋ฆฌ์•กํŠธ ์ƒํƒœ๊ฐ’(state)์ด๋ž€? - out.log

๋ฆฌ์•กํŠธ์—์„œ ์ƒํƒœ๊ฐ’(state)์ด๋ž€? ์ปดํฌ๋„ŒํŠธ ๋‚ด ๋ณ€๊ฒฝ ๊ฐ€๋Šฅํ•œ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ. UI(์—˜๋ฆฌ๋จผํŠธ)์— ๋ฐ˜์˜ํ•˜๊ธฐ ์œ„ํ•ด ์œ ์ง€ํ•ด์•ผํ•  ๊ฐ’ ๋ฌถ์Œ์ด๋‹ค. ๋ฆฌ์•กํŠธ ์ปดํฌ๋„ŒํŠธ์— ์ €์žฅํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€ํ™”ํ•˜๋ฉด UI๊ฐ€ ์ž๋™์œผ๋กœ ๊ฐฑ์‹ 

naon.me

https://abangpa1ace.tistory.com/241?category=905014 

 

[Jotai] React ์ „์—ญ ์ƒํƒœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

์ด์ „, ํ† ์ด๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด์„œ React์˜ ์ „์—ญ ์ƒํƒœ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด Recoil ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ ์šฉํ–ˆ๋˜ ์ ์ด ์žˆ๋‹ค. (๋งํฌ) [Recoil] ์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ - Recoil ์ •๋ณต๊ธฐ ๐Ÿง ์„œ๋ก  ๊ต‰์žฅํžˆ ์˜ค๋žœ๋งŒ์— ์“ฐ๋Š” ์„œ๋ก 

abangpa1ace.tistory.com

https://ui.toast.com/posts/ko_20210812

 

React ์ƒํƒœ ๊ด€๋ฆฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Zustand์˜ ์ฝ”๋“œ๋ฅผ ํŒŒํ—ค์ณ๋ณด์ž

TOAST UI Calendar์˜ ์ƒˆ๋กœ์šด ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์„ ๋„์ž…ํ•˜๊ธฐ ์œ„ํ•ด ์ฐธ๊ณ ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ Zustand์˜ ์ฝ”๋“œ๋ฅผ ๋ถ„์„ํ•ด๋ณธ๋‹ค.

ui.toast.com

https://recoiljs.org/ko/docs/introduction/core-concepts/

 

์ฃผ์š” ๊ฐœ๋… | Recoil

๊ฐœ์š”

recoiljs.org

https://ko.redux.js.org/introduction/getting-started/

 

Redux ์‹œ์ž‘ํ•˜๊ธฐ | Redux

์†Œ๊ฐœ > ์‹œ์ž‘ํ•˜๊ธฐ: Redux๋ฅผ ๋ฐฐ์šฐ๊ณ  ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ž๋ฃŒ

ko.redux.js.org

https://devbksheen.tistory.com/entry/Context-API-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0?category=1028639?category=1028639 

 

Context API๋ž€? ์†Œ๊ฐœ ๋ฐ ์‚ฌ์šฉ๋ฒ•

Context API๋ž€? Context API๋Š” ๋ฆฌ์•กํŠธ์— ๋‚ด์žฅ๋œ ๊ธฐ๋Šฅ์œผ๋กœ Props๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ํŠน์ • ๊ฐ’์ด ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋ผ๋ฆฌ ์‰ฝ๊ฒŒ ๊ฐ’์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์ค€๋‹ค. ์ฃผ๋กœ ํ”„๋กœ์ ํŠธ์—์„œ ์ „์—ญ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•  ๋•Œ ๋งŽ์ด ์‚ฌ

devbksheen.tistory.com