# jotai
## 前言
其實很多state management有一個概念很重要,資料處理與畫面渲染是兩件事情,以redux來説store只是負責資料的CRUD實際上他無法觸發react的render
### redux sub 介紹
```typescript
import { addTodo, toggleTodo, setVisibilityFilter, VisibilityFilters } from './actions'
// 記錄初始 state
console.log(store.getState())
// 每次 state 變更,就記錄它
// 記得 subscribe() 會回傳一個用來撤銷 listener 的 function
let unsubscribe = store.subscribe(() =>
console.log(store.getState())
)
// Dispatch 一些 action
store.dispatch(addTodo('Learn about actions'))
store.dispatch(addTodo('Learn about reducers'))
store.dispatch(addTodo('Learn about store'))
store.dispatch(toggleTodo(0))
store.dispatch(toggleTodo(1))
store.dispatch(setVisibilityFilter(VisibilityFilters.SHOW_COMPLETED))
// 停止監聽 state 的更新
unsubscribe()
```

### jotai sub
sub functions
```typescript
const subscribeAtom = (atom, listener) => {
const mounted = addAtom(atom);
flushPending();
const listeners = mounted.l;
listeners.add(listener);
if ((import.meta.env && import.meta.env.MODE) !== "production") {
storeListeners.forEach((l) => l("sub"));
}
return () => {
listeners.delete(listener);
delAtom(atom);
if ((import.meta.env && import.meta.env.MODE) !== "production") {
storeListeners.forEach((l) => l("unsub"));
}
};
};
```
### useAtom
```typescript
export function useAtomValue<Value>(atom: Atom<Value>, options?: Options) {
const store = useStore(options)
const [[valueFromReducer, storeFromReducer, atomFromReducer], rerender] =
useReducer<
ReducerWithoutAction<readonly [Value, Store, typeof atom]>,
undefined
>(
(prev) => {
const nextValue = store.get(atom)
if (
Object.is(prev[0], nextValue) &&
prev[1] === store &&
prev[2] === atom
) {
return prev
}
return [nextValue, store, atom]
},
undefined,
() => [store.get(atom), store, atom]
)
let value = valueFromReducer
if (storeFromReducer !== store || atomFromReducer !== atom) {
rerender()
value = store.get(atom)
}
const delay = options?.delay
useEffect(() => {
const unsub = store.sub(atom, () => {
if (typeof delay === 'number') {
// delay rerendering to wait a promise possibly to resolve
setTimeout(rerender, delay)
return
}
rerender()
})
rerender()
return unsub
}, [store, atom, delay])
useDebugValue(value)
return isPromise(value) ? use(value) : (value as Awaited<Value>)
}
```
重點這邊觸發react render的
```typescript
useEffect(() => {
const unsub = store.sub(atom, () => {
if (typeof delay === 'number') {
// delay rerendering to wait a promise possibly to resolve
setTimeout(rerender, delay)
return
}
rerender()
})
rerender()
return unsub
}, [store, atom, delay])
```
#### jotai回饋
```typescript
lucy: sub = useEffect的dependence 監聽
他不會影響渲染 要渲染要在裡面進行setState之類的行為
要即時render用useAtom
```