programing

"오류: 리듀서 실행 중에는 store.getState()를 호출할 수 없습니다."

newsource 2023. 2. 15. 22:06

"오류: 리듀서 실행 중에는 store.getState()를 호출할 수 없습니다."

완전히 기능하는 리액트 네이티브 앱을 Redux v4로 업그레이드했는데 다음 오류가 나타납니다.

오류: 오류: 오류: 오류:리듀서 실행 중에는 store.getState()를 호출할 수 없습니다.리덕터는 이미 상태를 인수로 받았습니다.가게에서 읽지 말고 상단 환원기에서 물려주세요.

문제는 다른 컴포넌트 내부에 여러 개의 컴포넌트가 있고 각각이 다른 컴포넌트를 가지고 있다는 것입니다.connect(mapStateToProps, mapDispatchToProps)(Component)그리고 이것이 올바른 실행 방법은 아니라고 생각합니다만, 적절한 실행 방법은 모르겠습니다.

어떤 방향이든 감사합니다!

스택 트레이스:

    This error is located at:
    in Connect(SideBarApp) (at SceneView.js:9)
    in SceneView (at createTabNavigator.js:10)
    in RCTView (at View.js:43)
    in RCTView (at View.js:43)
    in ResourceSavingScene (at createBottomTabNavigator.js:86)
    in RCTView (at View.js:43)
    in RCTView (at View.js:43)
    in TabNavigationView (at createTabNavigator.js:127)
    in NavigationView (at createNavigator.js:59)
    in Navigator (at createNavigationContainer.js:376)
    in NavigationContainer (at SceneView.js:9)
    in SceneView (at SwitchView.js:12)
    in SwitchView (at createNavigator.js:59)
    in Navigator (at createNavigationContainer.js:376)
    in NavigationContainer (at AppNavigator.js:36)
    in App (created by Connect(App))
    in Connect(App) (at index.ios.js:23)
    in Provider (at index.ios.js:22)
    in TheNewsApp (at renderApplication.js:32)
    in RCTView (at View.js:43)
    in RCTView (at View.js:43)
    in AppContainer (at renderApplication.js:31)

This error is located at:
    in NavigationContainer (at SceneView.js:9)
    in SceneView (at SwitchView.js:12)
    in SwitchView (at createNavigator.js:59)
    in Navigator (at createNavigationContainer.js:376)
    in NavigationContainer (at AppNavigator.js:36)
    in App (created by Connect(App))
    in Connect(App) (at index.ios.js:23)
    in Provider (at index.ios.js:22)
    in TheNewsApp (at renderApplication.js:32)
    in RCTView (at View.js:43)
    in RCTView (at View.js:43)
    in AppContainer (at renderApplication.js:31)

This error is located at:
    in NavigationContainer (at AppNavigator.js:36)
    in App (created by Connect(App))
    in Connect(App) (at index.ios.js:23)
    in Provider (at index.ios.js:22)
    in TheNewsApp (at renderApplication.js:32)
    in RCTView (at View.js:43)
    in RCTView (at View.js:43)
    in AppContainer (at renderApplication.js:31)
getState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79579:24
runComponentSelector@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:78896:56
initSelector@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79019:28
Connect(SideBarApp)@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:78969:29
constructClassInstance@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:20826:32
updateClassComponent@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:22393:35
performUnitOfWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24922:27
workLoop@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24955:47
renderRoot@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:24988:21
performWorkOnRoot@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25549:23
performWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25481:30
performSyncWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25456:20
requestWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25362:26
scheduleWork@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:25224:28
enqueueSetState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:20681:23
setState@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:2380:37
dispatch@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80901:27
navigate@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80517:24
nav@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:80470:44
combination@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79810:38
dispatch@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:79628:38
setLoginStatus@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:112247:19
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:112199:44
tryCallOne@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8818:16
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8919:27
_callTimer@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8162:17
_callImmediatesPass@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8198:19
callImmediates@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:8417:33
__callImmediates@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7741:32
http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7580:34
__guard@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7721:15
flushedQueue@http://localhost:8081/index.ios.bundle?platform=ios&dev=true&minify=false:7579:21
flushedQueue@[native code]
invokeCallbackAndReturnFlushedQueue@[native code]

문제는 redux-devtools-extension새로운 v2.16.0 릴리스에서 발생합니다.

수정을 기다리는 동안 몇 가지 해결 방법이 있습니다.

  1. 정상 버전 v2.15.5로 되돌립니다(Chrome의 경우).

    • https://github.com/zalmoxisus/redux-devtools-extension/releases/download/2.15.5/extension.zip 다운로드
    • 압축 해제
    • 유형chrome://extensionsurl에 접속하여 on으로 합니다.developer mode에서top right를 참조해 주세요.
    • 단추Load Unpacked표시됩니다.버튼을 클릭한 후 추출된 폴더를 선택합니다.
  2. 또는 일단 redux-devtool 확장을 비활성화합니다.

    • 브라우저 레벨 또는 코드(redex 스토어를 만드는 곳)를 통해 실행

참고로 이것은 OP의 질문을 해결하는 것이 아니라 개발자가 18년 11월 27일부터 아래의 에러 메시지를 수신하는 문제를 해결합니다.

Error: You may not call store.getState() while the reducer is executing. The reducer has already received the state as an argument. Pass it down from the top reducer instead of reading it from the store.


갱신하다

v2.16.2가 출시되었습니다.

이전에 확장을 비활성화한 사용자는 다시 활성화하고 Redux 개발 도구를 2.16.0에서 2.16.2로 업데이트 Redux 개발 도구를 업데이트하십시오.

내 경우 컴포트를 삭제해야 합니다.WithDevTools - Chrome용 플러그인

import { createStore, combineReducers, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extension';
import thunk from 'redux-thunk';

// const enhancer = composeWithDevTools(applyMiddleware(thunk))
const enhancer = applyMiddleware(thunk)

const store = createStore(reducers, enhancer);

제 프로젝트에서는요.이 문제는 어느 날 갑자기 나타났다.

솔루션:Chrome 확장 - Redux Devtools를 비활성화합니다.그러면 모든 것이 정상으로 돌아옵니다.

따라서 이러한 오류는 여러 브라우저에서 테스트하여 문제를 찾아야 합니다.

dr;dr

환원기에 부작용을 일으키는 코드가 없는지 확인하십시오!

순수 환원기

리덕스 리덕터는 순수해야 합니다.이것은 그들이 부작용을 가져서는 안 된다는 것을 의미한다.부작용은 덩크나 사가에게 돌아가야 한다.제 경우 리듀서는 다음과 같습니다.

case REDIRECT_ON_EVENT: {
  history.push('/some-route'); // side effect: redirection
  return {
    ...state,
    path: action.payload.path,
  };
}

history.push('/some-route');부분적인 상태 관리가 엉망이 되었습니다.리듀서에서 삭제한 후 동일한 액션유형으로 호출된 사가에 배치하면 문제가 해결됩니다.

function redirectToSomeRoute() {
  history.push('/some-route');
}

takeEvery(REDIRECT_ON_EVENT, redirectToSomeRoute),

확장 composeWithDevTool퀵픽스로 동작합니다.그러나 애플리케이션 상태를 추적하고 적절하게 관리하려면 확장 기능이 필요하다는 것은 누구나 알고 있습니다.그래서 오늘 문제가 생겼는데, 부디 지원해주십시오. 레독스

임시 회피책(크롬용)을 찾고 있는 경우는, https://github.com/zalmoxisus/redux-devtools-extension/releases/download/2.15.5/extension.zip 를 다운로드해, 폴더에 압축을 풀 수 있습니다.

chrome://extensions를 입력하고 왼쪽 위에서 개발자 모드를 켜고 Load Unpacked를 클릭하여 사용할 압축 해제 폴더를 선택합니다.

문제: https://github.com/reduxjs/redux-devtools/issues/413

솔루션 나에게 적합한

Redux Dev 도구의 Chrome 확장을 사용하지 않도록 설정합니다.또는 코드에서 로거를 제거합니다.

업데이트: Redux Dev 툴을 2.16.0에서 2.16.1 Update Redex Dev 툴로 업데이트합니다.

제 경우 개발 확장과 관련된 문제가 아닙니다.딥링크를 사용하는 동안 이 오류가 발생했습니다.리듀서 내부에서 루트 쿼리를 업데이트하고 있었습니다.setimeout 내의 url 조작과 관련된 래핑 로직에 의해 오류가 수정되었습니다.

폴리머 3을 사용한 PWA 빌드에서도 같은 에러가 발생했습니다.store.js는 또한 redex dev 툴을 사용하려고 했습니다.이 툴을 비활성화해야 했습니다.

...
// Sets up a Chrome extension for time travel debugging.
// See https://github.com/zalmoxisus/redux-devtools-extension for more information.
//const devCompose = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const devCompose =  compose;

// Initializes the Redux store with a lazyReducerEnhancer (so that you can
// lazily add reducers after the store has been created) and redux-thunk (so
// that you can dispatch async actions). See the "Redux and state management"
// section of the wiki for more details:
// https://github.com/Polymer/pwa-starter-kit/wiki/4.-Redux-and-state-management
export const store = createStore(
  state => state,
  devCompose(
    lazyReducerEnhancer(combineReducers),
    applyMiddleware(thunk))
);
...

이것이 제가 한 일입니다: 방금 제 store.js 파일에서 Chrome Redex Devtools Extension 행을 코멘트했습니다.

....

 const store = createStore(
  rootReducer,
  initialState,
  compose(
    applyMiddleware(...middleware)
   ///This line--> window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 
  )
);

....

그리고 이 문제는 한 시간 전에 시작되었다.모두 알다시피, 개발 중에 확장이 매우 편리하기 때문에 당국의 진정한 수정을 기다려 봅시다.

지금 고쳐야 해.레덕스 개발 도구를 2.16.0에서 2.16.1로 업데이트

https://github.com/zalmoxisus/redux-devtools-extension/issues/588#issuecomment-442396540

크롬에서 이 문제가 발생했습니다.리덕스 버전을 4.0.2에서 3.7.2로 다운그레이드하여 수정했습니다.

npm uninstall redux

npm install redux@3.7.2

주의: Saga를 사용하고 있습니다.

내 경우 리듀서 안에 내비게이션 코드를 추가했다.

    sendOTPSuccess: (state, action) => {
      state.wip = false;

      RootNavigation.navigate('LoginOTPScreen');
    },

처음에는 동작하고 있었지만, 새로운 화면이라고 불리는 상태에서 사용/액세스 했을 때

import { useDispatch, useSelector } from "react-redux";
import * as sessionActions from "../../models/session";

const LoginOTP: () => Node = (props) => {
  const session = useSelector(sessionActions.selectSession);
  const dispatch = useDispatch();
  ...

에러가 표시된다.

“Error: You may not call store.getState() while the reducer is executing.”

원인

환원제는 순수한 기능이어야 합니다.payload를 받아들여 스테이트를 변경할 필요가 있습니다.또 다른 무언가가 부작용으로 여겨집니다.

, 이 컴포넌트도 됩니다.state데이터 및 상태 수정이 아직 완료되지 않았습니다.이것이 문제의 원인.

솔루션

의 비비 respect respect respect respect로 입니다.saga

// worker Saga:
function* sendOTPSaga({ payload }) {
  const { phoneNumber } = payload;
  try {
    const response = yield call(Api.sendOtp, { phoneNumber });
    if (response.status == 200) {
      yield put(sessionActions.sendOTPSuccess(response.data));
      RootNavigation.navigate('LoginOTPScreen'); // <---- Here
    ...

언급URL : https://stackoverflow.com/questions/51503198/error-you-may-not-call-store-getstate-while-the-reducer-is-executing