reactjs - 调度未调用 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>
)
}
}
解决方案
我发现像这样映射我的调度解决了我的问题 - 但我不是 100% 确定为什么......:
const mapDispatchToProps = (dispatch: any, ownProps: OwnProps): DispatchProps => {
return {
getSearchResults: () => dispatch(getSearchResults()),
}
}
推荐阅读
- javascript - node.js 中负责系统调用的内置模块有哪些?
- javascript - 赛普拉斯中难以访问窗口对象
- javascript - 在循环内的 Promise.all 之后调用函数
- react-native - 使用 react-native-router-flux 时如何在屏幕之间传递道具
- c# - 尝试在 Visual Studio 2015 中创建新查询时出错
- r - R:在 R 中获取更多信息错误消息
- java - Spring Boot + AWS Linux + Oracle 数据库
- javascript - 如何在 HTML 的下拉列表中设置条件?
- lodash - Lodash:如何找到每个id的最大值和最小值
- cakephp - 如果 cakephp 3 中的包含为空,则删除父数组