datas, paths, isRoot, isLoading
- 스토어 사용 & 리덕스 따라하기
setState
,getState
,subscribe
,unsubscribe
,notify
, 정합성체크
setState(key, newState)
⇒ 1. 정합성체크 2. this.state=newState 3.notify
subscribe(key, listener)
⇒ this.listeners.push(listener)
- App에서 state를 모두 갖고 있고, 컴포넌트는 state 대신 props를 이용
- 각 state의 변경사항이 있을 때만 각 render 호출
//Todo: dispatch, , subscribe, unsubscribe //TODO: 객체 멤버 함수들 이름을 키로, 값을 각 state 초기값으로 const state = {} const reducers = rootReducer Object.keys(reducers).forEach(reducerName => state[reducerName] = reducers[reducerName](action=""))) const store = new Store.createStore({ selectedImageUrl, currentPaths, isLoading }) getState = () => state state는 { selectedImageUrl: null, currentPaths: [] isLoading: false } -- const selectedImageUrl = (state=null, action) => { switch(action.type) { case "CLICK_IMAGE": return action.imageUrl case "REMOVE_IMAGE": return null default: return state } } this.setState({ ...this.state, selectedImageUrl: `${COMMON_IMAGE_URL}${node.filePath}` }) store.dispatch({ type: "CLICK_IMAGE", imageUrl: `${COMMON_IMAGE_URL}${node.filePath}` }) store.dispatch({ type: "REMOVE_IMAGE" }) -- const currentPaths = (state=[], action) => { switch(action.type) { case "GO_TO_SUB": return [...state, action.subNode] case "GO_BACK": return state.slice(0, state.length-1) case "GO_BACK_TO_PARENTS": return state.slice(0, action.parentIdx+1) default: return state } } this.setState({ ...this.state, paths: newPaths.slice(0, clickedIdx+1) }) this.setState({ ...this.state, paths: [...this.state.paths, node] }) this.setState({ ...this.state, paths: newPaths }) store.dispatch({ type: "GO_BACK_TO_PARENTS", parentIdx: clickedIdx }) store.dispatch({ type: "GO_TO_SUB", subNode: node }) store.dispatch({ type: "GO_BACK" }) -- const isLoading = (state=false, action) => { switch(action.type){ case "LOADING" return true case "UNLOADING" return false } } this.setState({ ...this.state, isLoading: true }) store.dispatch({ type: "LOADING" }) store.dispatch({ type: "UNLOADING" })
—
//리듀서 : state 복사본을 각 액션에 따라 조작해서 새로운 state 반환 //cf) setState: 현재 state를 변경, getState: 현재 state를 반환 const reducer = (state=[], action) => { switch(action.type) { case "ADD_TODO": //상태를 어떻게 조작할까를 정의 return [...state, action.text] //새 상태를 반환 => store의 상태가 이걸로 바뀜 default: return state } } const store = createStore(reducer, initialState) //이제 스토어는 set/getState를 가짐 store.dispatch({ type: "ADD_TODO", text: "과제 하기" }) // 상태를 setState하는 것 /* const increment = () => { //일반적으로 액션 생성자 사용 return { type: 'counter/increment' } } store.dispatch(increment()) */ store.getState() // 현재 상태 const handleChange() { } store.subscribe(handleChange) //액션이 dispatch될 때마다 해당 리스너가 실행됨