首页 > 解决方案 > 调度未调用 Thunk Action - 使用 Typescript

问题描述

我正在使用 React、Redux、Redux-Thunk 和 Typescript(noobie)。当我用 thunk 调用一个动作时,我可以看到该动作被调用(使用 console.log)但调度不是。我已经使用 mapToDispatch 连接了这个动作,并使用 this.props.(action) 从组件调用它。我无法弄清楚为什么没有调用调度。这是我的代码:

store.ts

import { applyMiddleware, combineReducers, createStore, Store, compose } from 'redux'
import { ReducerMap, StoreShape, SYSTEM_STATE_NAMESPACE_KEY } from './types'
import thunkMiddleware from 'redux-thunk'
import systemReducer from './globalData/reducer'
import { Environment, getCurrentEnvironment } from '../services/api.service'

let reducerMap: ReducerMap = { [SYSTEM_STATE_NAMESPACE_KEY]: systemReducer }

const isDevelopmentEnvironment = [Environment.LOCALHOST, Environment.STAGING].includes(getCurrentEnvironment())

export default function configureStore() {
  const middleware = [thunkMiddleware]
  const middlewareEnhancer = applyMiddleware(...middleware)

  let composedEnhancers = isDevelopmentEnvironment
    ? (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
    : compose

  const preloadedState = (window as any).__PRELOADED_STATE__;

  delete (window as any).__PRELOADED_STATE__;

  return createStore(combineReducers(reducerMap), preloadedState, composedEnhancers(middlewareEnhancer))
}

export const store = configureStore()

export function getStore() {
  return store
}

动作.js


import { SearchActionTypes, SearchNamespaceShape } from './types'
import axios from '../../../services/axiosInstance'
import { Action } from 'redux'
import { StoreShape } from '../../../store/types'
import { getAPIDomain } from '../../../services/api.service'

export function getSearchResults (): ThunkAction<void, StoreShape, void, Action> {
  console.log('inside function')
  return (dispatch) => {
    console.log('inside dispatch')
    const body: object = {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "title": "CEO"
              } 
            }
          ]
        }
      }
    }
    axios.post(
      'https://' + getAPIDomain() + '/proxy-service/ROOT/search/_search',
      body
    )
    .then((response: object):any => console.log(response))
    .catch((response: object):any => console.log(response))
  }
}

容器

import { connect, Provider } from 'react-redux'
import * as React from 'react'

import { getStoreForSearch } from './data/store'
import { getGlobalData } from '../../store/globalData/selectors'
import UnconnectedSearchPage, { StateProps, DispatchProps, OwnProps } from './search'
import { StoreShape } from '../../store/types'
import { getSearchResults } from './data/actions'

const SearchContainer: React.FC = () => {
  return (
  <Provider store={getStoreForSearch({})} >
    <ConnectedSearchPage textToDisplay='Hello World'/>
  </Provider>)
}

function mapStateToProps (state: StoreShape, ownProps: OwnProps): StateProps { 
  return(
    { 
      system: getGlobalData(state)
    }
  )
}
const mapDispatchToProps = (dispatch: any, ownProps: OwnProps): DispatchProps => ({
  getSearchResults: () => dispatch(getSearchResults)
})

const ConnectedSearchPage = connect<StateProps, DispatchProps, OwnProps>(mapStateToProps, mapDispatchToProps)(
  UnconnectedSearchPage
)

export default SearchContainer

零件

import React from 'react'
import { ThunkAction } from 'redux-thunk'
import { Action } from 'redux'

import { GlobalDataNamespaceShape } from '../../store/globalData/types'
import { FullStoreShape } from '../../store/types'

export interface OwnProps {
  textToDisplay: string
  labelText?: string
}

export interface StateProps {
  system: GlobalDataNamespaceShape
}

export interface DispatchProps {
  getSearchResults: () => ThunkAction<void, Partial<FullStoreShape>, undefined, Action<object>>
}

export type SearchComponentProps =  StateProps & DispatchProps & OwnProps

interface SearchState {
  greeting: string
}

export default class UnconnectedSearchPage extends React.Component<SearchComponentProps, SearchState> {
  constructor(props: SearchComponentProps) {
    super(props)
    this.state = { greeting: props.textToDisplay }
  }

  setGreeting( greeting: string): void {
    this.setState({ greeting })
  }

  render () {
    console.log(this.props)
    return (
    <div>
      <h2>Search Page</h2>
      <div>{`Greeting: ${this.state.greeting}`}</div>
      <label>{this.props.labelText}</label>
      <input
        type='text'
        value={this.state.greeting}
        onChange={event => this.setGreeting(event.target.value)}
      />
      <button onClick={() => {
        this.props.getSearchResults()
      }}>Get Search Results</button>
    </div>
    )
  }
}

标签: reactjstypescriptreduxredux-thunk

解决方案


我发现像这样映射我的调度解决了我的问题 - 但我不是 100% 确定为什么......:

const mapDispatchToProps = (dispatch: any, ownProps: OwnProps): DispatchProps => {
  return {
    getSearchResults: () => dispatch(getSearchResults()),
  }
}

推荐阅读