묻고 답해요
141만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Redux vs MobX (둘 다 배우자!)
context api, redux를 혼용하는건 별로일까요?
웹게임이 여러개 있으면서 일부는 사용자 간에 대전도 가능한 경우서버와 주고받는 데이터(대전 게임의 진행 데이터 포함)는 redux로 관리하고, 1인용 게임 등 다른 곳에서 사용할 일이 없는 게임의 데이터들은 context api로 관리하려고 하는데 적절한가요?
-
미해결Redux vs MobX (둘 다 배우자!)
섹션 3 mobx autorun 관련 질문입니다.
const state = observable({ name: "zero", age: 28, married: false, }); autorun(() => { console.log("autorun : " + state.name); }); reaction( () => state.name, () => { console.log("reaction : name changed"); } ); runInAction(() => { state.name = "nureongi"; state.age = 26; }); const action1 = action(() => { state.married = true; }); const action2 = action(() => { state.married = false; }) action1(); action2(); /** autorun : zero autorun : nureongi reaction : name changed **/안녕하세요! 강의 잘 듣고 있습니다. 제가 궁금한 것은 강의에서 autorun은 observable에 담긴 모든 state가 변경될 때 마다 실행된다고 하셨는데실제 실험해보니 결과가 조금 다르게 나온 것 같았습니다.그래서 확인해보니 다음과 같이 동작한다는 사실을 알게 되었습니다. autorun이 정의될 때 한 번 실행autorun 함수 내부에서 참조하고 있는 observable state가 변경될 때 실행 아마 버전이 업데이트 되면서 바뀐 것 같은데 제가 알게 된 사실이 맞을까요?
-
미해결Redux vs MobX (둘 다 배우자!)
thunk 미들웨어 잡업 중 논리로직 단계? 질문이 있습니다.
미들웨어가 들어간 이후 궁금한 부분이 있어서 질문 합니다.리덕스에 dispatch를 하면 리듀서가 이를 받고, 기존에 액션함수를 만들었다면, 만든 액션함수를 매칭 시켜서 상태관리를 하잖아요? 그래서 이번 강좌(2-4.redux-thunk)에서도 비동기 로그인을 디스패치 하잖아요?store.dispatch( logIn({ id: 1, name: "goodsosbva", admin: true, })이 이후에 액션에 정의한// async action creator const logIn = (data) => { return (dispatch, getState) => { // async action dispatch(logInRequest()); try { setTimeout(() => { dispatch( logInSuccess({ userId: 1, nickname: "khszzang!", }) ); }, 2000); } catch (e) { dispatch(logInFailure(e)); } }; };여기로 가서 로직을 하잖아요? 이때, 만들어둔 미들웨어가const thunkMiddleware = (store) => (next) => (action) => { if (typeof action === "function") { // 비동기 return action(store.dispatch, store.getState); } return next(action); }; const enhancer = applyMiddleware(firstMiddleware, thunkMiddleware); const store = createStore(reducer, initialState, enhancer); 어떤 순간에 작동하는지가 감이 안와서 질문드립니다.이전 강의에서는 dispatch -> 미들웨어 -> reducer라고 하신거 같은데요.이걸 보고 나름 이해하려고 노력했는데...걸리는 점은지금은 비동기로 만든 액션함수가 하나니까 미들웨어에서 하나로 매칭될 수 있겠는데..?여러개면 어떻게 되는거지라는? 의문입니다.제질문이 좀 난해한거같기도 한데요. 요약하면, 미들웨어가 어디서 동작하는지 모르겠다.비동기 미들웨어 요청을 할때 액션함수를 알맞게 어떻게 요청하는지 몰라서 질문드립니다.
-
해결됨Redux vs MobX (둘 다 배우자!)
rootSaga에서 call를 사용하는 이유가 궁금합니다.
export default function* userSaga() { yield all([fork(watchLogin), fork(watchHello)]); } export default function* rootSaga() { yield all([call(userSaga), call(postSaga)]); }userSaga에서는 순서가 없기 때문에 fork를 썻다고 하셧는데 rootSaga에서는 call을 쓰는 이유가 있나요?rootSaga도 실행하는데 순서가 크게 중요할 것 같지 않아서 call을 써야 하는 이유가 있는지 궁금합니다.
-
해결됨Redux vs MobX (둘 다 배우자!)
observable의 함수를 익명함수로 바꿔봤습니다.
const userStore = observable({ isLogginIn: false, data: null as any, logIn(data: any) { this.isLogginIn = true; setTimeout(() => { this.data = data; this.isLogginIn = false; postStore.data.push(1); }, 2000); }, logOut() { this.data = null; }, }); const userStore = observable({ isLogginIn: false, data: null as any, logIn: (data: any) => { userStore.isLogginIn = true; setTimeout(() => { userStore.data = data; userStore.isLogginIn = false; postStore.data.push(1); }, 2000); }, logOut: () => { userStore.data = null; }, });평소에 선언적함수보다 익명함수로 코딩을 하고 있어서 코딩스타일을 맞추고 싶어위 코드를 밑에처럼 익명함수로 바꿔봤습니다.익명함수에 화살표함수를 쓰니 this가 바인딩되어undefind가 된것 같은데 그래서 this 대신 userStore에서 접근하는 방식으로 바꿔봤습니다.this대신에 useStore로 접근해도 괜찮은지 잘 모르겟습니다.
-
해결됨Redux vs MobX (둘 다 배우자!)
useSelector 리랜더링 질문있습니다.
const userData = useSelector((state) => state.user.data); const isLoggingIn = useSelector((state) => state.user.isLoggingIn); const postData = useSelector((state) => state.posts.data);강의에서는 useSelector를 한번씩 써서 가져오면 리랜더링을 줄여줄 수 있다고 하셧는데 const { userData, isLoggingIn, postData } = useSelector((state) => ({ userData: state.user.data, isLoggingIn: state.user.isLoggingIn, postData: state.posts.data, }));이처럼 객체를 새로 만들어서 리턴해줘도 동일하게 리랜더링을 줄여줄 수 있는지 궁금합니다.
-
해결됨Redux vs MobX (둘 다 배우자!)
비동기 action 타입을 뭘로 지정해야 할까요?
//비동기 const logIn = (data: any): any => { return (dispatch: Dispatch<AnyAction>, getState: any) => { dispatch(logInRequest(data)); try { return setTimeout(() => { dispatch(logInSuccess({ id: 1, name: "userName", admin: true, }) ); }, 2000); } catch (error) { return dispatch(logInFailure(error)); } }; }; const logInRequest = (data: any): AnyAction => { return { type: "LOG_IN_REQUEST", data, }; }; const logInSuccess = (data: any): AnyAction => { return { type: "LOG_IN", data, }; }; const logInFailure = (error: unknown) => { return { type: "LOG_IN_FAILURE", error, }; }; //login을 dispatch store.dispatch(logIn({ id: 1, name: "userName", admin: true })); 강좌코드를 타입스크립트로 변환해보고 있는중에 궁금한게 있어서 질문드립니다.login 비동기 함수가 return 하는게 함수이고setTimeOut함수 때문에 함수반환타입도 Action 타입이 아니라서최종적으로 리턴타입이 () => NodeJS.Timeout | AnyAction이 되는것 같습니다store.dispatch(login())을 하면 타입에러가 나오는데login 리턴타입을 any로 바꿔주는거 말고 다른 방법으로 해결 할 수 있는 방법이 있을까요?
-
해결됨Redux vs MobX (둘 다 배우자!)
redux-thunk질문
현재 강의 프로젝트 파일에서는 툴킷을 설치하지도, redux-thunk를 따로 설치하지도 않았는데 어느 부분이 thunk인 건가요? 여기서 말하는 thunk미들웨어는 그냥 이름만 thunk인 것이고 진짜 redux-thunk의 thunk미들웨어는 툴킷 영상에서 사용한 createAsyncThunk인가요?
-
해결됨Redux vs MobX (둘 다 배우자!)
state 변경 시 질문
영상에서는 배열타입의 state의 요소를 제거해주기 위해 깊은 복사한 다음 delete를 쓰는 식으로 했었는데 급하게 구현한다고 깊은 복사를 쓴 것이고 실제로는 그렇게 하면 안된다고 하셨는데 만약 immer를 쓰지 않는다면 실제로는 어떻게 요소 제거를 해야하나요?
-
미해결Redux vs MobX (둘 다 배우자!)
state변경 시 질문
영상에서는 빠르게 구현한다고 배열타입의 state의 요소를 제거해주기 위해 깊은 복사한 다음 delete를 쓰는 식으로 했었는데 immer쓰지 않는다면 실제로는 요소 제거를 어떻게 해야하나요?
-
해결됨Redux vs MobX (둘 다 배우자!)
firstMiddleware와 thunkMiddleware 순서 질문
applyMiddleware에 firstMiddleware와 thunkMiddleware를 인자로 넣을 때 넣는 순서에 따라서 어느 미들웨어 먼저 실행되는지 달라지나요?
-
해결됨Redux vs MobX (둘 다 배우자!)
객체 동적 다이나믹 속성?? 질문
[logIn.pending](state, action) { state.isLoggingIn = true; }이 문법 정확한 명칭이 뭔가요? 구글링 하고 싶은데 원하는 결과가 안나오네요
-
해결됨Redux vs MobX (둘 다 배우자!)
미들웨어 질문
firstMiddleware의 dispatch(action)이후 코드에 넣은 console.log('액션 끝') 코드가 store.subscribe 이후에 실행되는 것이면 dispatch와 reducer 사이 뿐만 아니라dispatch가 실행되고 reducer가 실행되고 state가 변경되고 나서 동작을 추가할 수 있다는 말인가요?dispatch -> 미들웨어 -> Reducer -> 미들웨어이게 맞나요?
-
미해결Redux vs MobX (둘 다 배우자!)
리덕스 사가 실습 파일 확인 부탁드립니다!
안녕하세요 제로초님 좋은 강의 잘 보고 있습니다!리덕스 사가 실습을 해보고 싶어서 노드버드 깃헙 파일 클론해서 npm i 하고 실행을 하니 next랑 react dependency가 발생해 version update도 해봤지만 잘 안되더라구요 ㅠㅠ 혹시몰라서 ch7도 해봤지만 잘 되지 않았습니다.ch3 코드기준으로 실습하면 좋던데 혹시 실습파일 확인 후 재업로드 한번 부탁드려도 될까요? ㅠㅠ
-
해결됨Redux vs MobX (둘 다 배우자!)
1-6 강의에서 질문 있습니다!
안녕하세요 제로초님! 강의를 듣던 도중 이해가 되지 않는 부분이 있어서 질문 드립니다.위의 사진은 제가 실행해본 테스트 예제입니다! 기존 posts 내용에 즉 prevState에 새로운 데이터를 추가하려면 initalState가 아닌 추가하려는 데이터 객체의 바로 이전 객체의 데이터를 복사하는게 맞다고 생각하는데 어째서 intialState로 작성하셨는지 궁금합니다. 또한 reducer에서의 prevState는 맨 처음에만 store에 저장되어 있는 initialState를 받고 이후에는 바로 이전 state를 받는 것이 맞는지 궁금합니다!예를 들면 A -> B -> C 가 있다고 하면 A -> B 에서 A는 B의 prevState,B -> C 에서는 B는 C의 prevState로 이해하고 있습니다.
-
해결됨[리뉴얼] React로 NodeBird SNS 만들기
nodebird 강의 redux 대신 mobx 써서해보고있는데
이런 경고가뜨는데 왜 뜨는걸까요? RootStoreProvider 쪽에서 문제가 되는것같아서 찾아봤는데 RootStoreProvider에서 경고가 뜨는데 저게 찾아보니 스택오버플로에 hooks 쓸때 16버전 부터는 useEffect() 로 감싸라는것같은데 서버사이드렌더링은 클라이언트에서 화면그리기전에 먼저 store 세팅하는거라 어떻게 해야될까요?
-
해결됨Redux vs MobX (둘 다 배우자!)
next 에서 mobx
여기있는 예제를 보고 next 에서 mobx 사용중인데 https://dev.to/ivandotv/mobx-server-side-rendering-with-next-js-4m18 깃헙코드: https://github.com/ivandotv/mobx-nextjs-root-store 참고로 저 예제에선 rootStore를 각 store 마다 생성자에 넘겨주긴했지만 직접적으로 rootStore를 사용하지 않았습니다. 그러나 제가 사용하는 서비스는 A store B store가 있을때 B store에서 action이 발생했을때 A store 에대한 상태가 바뀌어야되서 rootStore를 생성자로 받아야될것같더라고요 이 예제를 참고했습니다. 저기서 store 만들떄 RootStore 만들고 Counter Store에 CountStore 에 this 를 넘겨줘서 이렇게 rootStore 를 받고있는데 mobx devtools 보니까 makeObservable 에 root 를 넣지도 않았는데 devtools 에서 countStore 안에 RootStore가 있고 그 RootStore 안에 countSotre가 있고 1. 이렇게 재귀처럼 state 가 존재하는데 성능에 영향을 미칠까요? 2. 특정 변수만 observe 하고싶지 않은데 어떻게 하는게 좋을까요? 전 makeobservable 에 observable을 설정안해주면 안될줄 알았는데 devtools를 보니 rootStore가 있어서요. devTools에 있는 이유가 아마 annotation 에서 observable를 세팅해주는건 observable한 값이 변경됬을때 observer() 를 감싼 컴포넌트에서 리렌더링 하기위해 있는것같더라고요 2-1. 제 개인적으로 이 문제를 해결해보고자 이런식으로 넣긴 했거든요 makeObservable 의 첫번째 인자가 target 인데 감지할 state 를 넣는것같더라고요 두번째 인자에는 annotation (action인지 observable인지)붙혀주는것같아서 첫번째 인자에서 this 는 클래스를 가르키니까, root 도 같이 traget 된것같아 this에 대한 값을 바꾸면 될것같아서 state 변수를만들고 const state = this; 를 하면 참조되는 문제때문에 {...this} 이런식으로 복사해주고 root를 undefined 해주고 makeObservable에 this 대신 state 변수를 넘기니 rootStore가 devtools에 안나오는데 이렇게 해도 되는건가요?
-
해결됨Redux vs MobX (둘 다 배우자!)
mobx makeAutoObservable 과 mobx로 비동기처리해야될때 질문입니다.
class Store{ repository; rootStore; num = 0; constructor(repository,rootStore){ makeAutoObservable(this); this.repository = repository; this.rootStore = rootStore; } addnum = ()=>{ num++; } } mobx makeautoObservable 관련 질문입니다. 대충 이런식으로 store 가 있는데 makeAutoObservable이 알아서 action 이랑 observable을 지정해줍니다. 1-1. respository와 rootStore는 observable 하게 하고싶지 않은데 mobx devtools를보니 repository와 rootStore를 감지하고 있더라고요 특정 변수 또는 함수를 autoObservable 에 제외시킬수 있나요? repository 나 rootStore 앞에 private 키워드를 줘봤는데도 감지하고 있었습니다. 1-2. 위처럼 메모리에 불필요한 상태값까지 감지하게되면 나중에 state 가 커지면 성능과 메모리 차지에 큰 영향을 끼칠까요? mobx로 비동기 처리해야될때 질문입니다. 네트워크 요청해서 데이터를 보여줘야되는데 리스트로 항목 4개 보여주고 화살표로 다음 페이지버튼 보거나 이전페이지 버튼 보게 하고 있습니다. 다음페이지로 넘기면 네트워크 요청하고 응답받으면 데이터를 보여주게되고 요청을 날릴때는 빈화면이고 요청에대한 응답을 받았을때 데이터를 뿌려줘야됩니다. <button onClick = {()=>store.loadPrevious()}>previous</button> {store.listData && <MyListComponent data={store.listData.slice(store.page*4,store.page+4)}/>} <button onClick = {()=>store.loadNext()}>next</button> 이런식으로 store.listData 가 있을때 컴포넌트가 나오게 했습니다. 첫화면 로딩시 즉 useEffect() 에서 요청날렸을땐 제대로 동작하는데 다음페이지 버튼을 누르면 이미 store.listData는 이미 null이 아니기떄문에 네트워크요청 응답을 받기도전에 화면을 넘겨서 데이터를 제대로 뿌려주지를 못합니다. 2-1. 이런경우는어떻게 처리하는게 좋을까요?
-
해결됨Redux vs MobX (둘 다 배우자!)
runInAction 에 비동기
mobx react next 로 하고 있는데 runInAction 에서 비동기처리를 하려면 어떻게 해야되나요? Component.tsx const store = useIndexStore(); useEffect(() => { const fetchData = async () => { await store.loadNewMemberData(); console.log(store.newMember) } fetchData(); }, []) 일단 훅스 컴포넌트에서 useEffect에서 store 에 저장된 정보를 불러와야되는데 Promise 기때문에 따로 함수를 만들어줘서 호출을 했고요. useEffect 뜯어보니 함수 리턴타입이 void|Destructor(?) 라 Promise 타입을 못받아서 저렇게 만들었습니다. 1. useEffect 에서 비동기 작업을 할때 저렇게 async 함수 만들어서 호출해야되는건가요? 2. async 함수를 만들었으면 꼭 await 으로 호출안해도 되는건가요? store.ts class IndexStore { root; repository rtrMenu: MenuItem[] = []// constructor(root: RootStore, repository: BaseRepository) { this.root = root this.repository = repository makeAutoObservable(this) } loadRealtimeRequestData = async (): Promise<void> => { runInAction(() => { this.rtrMenu =this.repository.getRealTimeRequestItem() }); } } store에선 loadRealtimeRequestData() 함수에서 네트워크 요청한 결과를 받습니다. await this.repository.... 여기가 await axios.get() 이런 역할을 하게 되는데 then 을 하면 쉽게 해결될문제지만 async awiat 으로 runInAction 안에서 처리할려면 어떻게 해야되나요?
-
미해결Redux vs MobX (둘 다 배우자!)
reaction 중첩 실행 문제
이렇게 사용하고있습니다. user_email이 변경되는 과정에서 console.log(value) 이게 onChange가 일어날 때마다 한 번씩만 실행되어야하는데 예를들어 'asdf'를 입력한다고 가정할 때 log에는 아래와 같이 찍힙니다. LOG => a LOG => as LOG => as LOG => asd LOG => asd LOG => asd LOG => asdf LOG => asdf LOG => asdf LOG => asdf 이렇게 점차 1개씩 스택이 쌓이듯 중첩되어 실행이되는데 제가 이상한건지 mobx가 이상한건지 감이 안 잡힙니다.. react-native 환경에서 사용하려합니다.