TypeError: Невозможно прочитать свойство неопределенного mapStateToProps - PullRequest
1 голос
/ 02 апреля 2019

Я обнаружил ошибку при связывании моего компонента с магазином.

TypeError: Невозможно прочитать свойство 'errorMessage' из неопределенного

Function.mapStateToProps [as mapToProps]

  37 | const mapStateToProps = (state: AppState) => ({
> 38 |   errorMessage: state.errorRedux.errorMessage,
  39 |   error: state.errorRedux.error,
  40 | })

Я не могу понять, в чем проблема. Не следует прислушиваться к ошибке, поскольку я решил сделать сообщение условно.

  1. Я попытался установить errorMessage: string | undefined | null безуспешно.
  2. Я пытался errorMessage: "[INTERFACE"] безуспешно.
  3. Я пытался errorMessage?: string Я думаю, что проблема может заключаться в расширении интерфейса ErrorHandlerProps, но я уже расширил mapStateToProps?
import { Dispatch, Action } from "redux"
import { connect } from "react-redux"
import { AppState } from "reducers"
import { showError } from "data/error_handler"

class ErrorHandler extends React.Component<
  ReturnType<typeof mapStateToProps> & ReturnType<typeof mapDispatchToProps>
> {
  public render() {
    const { onShowError, error, errorMessage } = this.props

    let showTheError =
      this.props.error === true ? (
        <Snackbar
          open={error}
          message={errorMessage}
          autoHideDuration={5000}
        />
      ) : null

    return (
      <div>
        <RaisedButton onClick={onShowError} label="Toggle ErrorHandler" />
        {showTheError}
      </div>
    )
  }
}

const mapStateToProps = (state: AppState) => ({
  errorMessage: state.errorRedux.errorMessage,
  error: state.errorRedux.error,
})

const mapDispatchToProps = (dispatch: Dispatch<Action>) => {
  return {
    onShowError: () => dispatch(showError()),
  }
}

export default connect(
  mapStateToProps,
  mapDispatchToProps
)(ErrorHandler)

data/interfaces.ts

export interface ErrorHandlerProps {
  error: boolean
  errorMessage: string
}

data/reducer.ts

import { ErrorHandlerProps, ActionTypes } from "./"

const initialState: ErrorHandlerProps = {
  error: false,
  errorMessage: "",
}

export default (
  state: ErrorHandlerProps = initialState,
  action: ActionTypes
) => {
  switch (action.type) {
    case "SHOW_ERROR":
      return {
        ...state,
      }
    default:
      return state
  }
}

reducers.ts

import { reducer as errorHandler, ErrorHandlerProps } from "data/error_handler"

const appReducer = combineReducers({
  errorHandler
} as any)

export type AppState = {
  errorRedux: ErrorHandlerProps
}

store.ts

import { createStore, applyMiddleware, compose } from "redux"
import { routerMiddleware } from "react-router-redux"
import thunk from "redux-thunk"
import rootReducer, { AppState } from "reducers"

const initialState = {}
const middleware = [thunk, routerMiddleware(history)]
const composedEnhancers = compose(applyMiddleware(...middleware), ...enhancers)
const store = createStore(rootReducer, initialState, composedEnhancers)

export default store
export const getState = () => store.getState() as AppState

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Будет проще, если мы увидим, как вы создали свой магазин.

Обычно эта проблема возникает, когда вы используете combineReducers, потому что он создает объект редукторов, и именно это mapStateToProps получает вместо состояния напрямую.

import { createStore, combineReducers } from "redux";
import testReducer from "./reducer";
import testReducer2 from "./reducer2";

// ----
// using combine reducers will make the state in mapStateToProps to be an object of all the reducers combined, so you have to access it like state.testReducer.value or state.testReducer2.value

const rootReducer = combineReducers({
  testReducer,
  testReducer2
});
// ----

// ----
// while passing a reducer directly will not have the same effect and the state will be accessible like state.value in mapStateToProps

const rootReducer = testReducer;
// ----

const store = createStore(rootReducer);

export default store;

См. Следующую песочницу: https://codesandbox.io/s/k3ojkqxy57

0 голосов
/ 02 апреля 2019

Попробуйте изменить это на:

const mapStateToProps = (state: AppState) => ({
   errorMessage: state.getIn(['errorRedux', 'errorMessage'], 'default value here'),
   error: state.getIn(['errorRedux', 'error'], ], 'default value here'),
})
...