【问题标题】:Dispatch is not a function in Server Side RenderingDispatch 不是服务器端渲染中的功能
【发布时间】:2018-11-12 04:25:32
【问题描述】:

我遇到了 redux-thunk 的问题,它只是没有将调度传递给我的动作创建者。我正在记录它,但它仍然未定义:

这是我的动作创建者:

import * as types from './actionTypes'
import Service from '../service'



export const fetchFromApi = payload => {
  return { type: types.FETCH_FROM_API_TEST, payload }
}


export const fetchApiTestAction = () => dispatch => {
  return Service.GetUsers().then( _data => {
    dispatch(fetchFromApi( _data.data )) // you can even distructure taht like fetchFromApi(({ data }))
  }).catch ( err => {
    // error catching here 
    // you can even call an failure action here...
    // but sorry about it , i have no time for that , im sorry :(
    throw (err)
  })
}

这是我的 Service.js 类

// Basic fetch
  async basicFetch(url, options, headers = this.authernticateHeader) {
    let fetchOptions = {}
    if(options.headers) {
      fetchOptions = {
        mode: 'cors',
        cache: 'default',
        ...options
      }
    } else {
      fetchOptions = {
        mode: 'cors',
        cache: 'default',
        ...options,
        headers
      }
    }


    // log before sending the request...
    // console.log(url, fetchOptions, fetchOptions.headers.get('Content-Type') )

    try {
      const response = await fetch(
        `${this.serverAddress}${url}`,
        { ...fetchOptions }
      )

      if(!response.ok) {
        throw {
          message: response.statusText,
          api: `${options.method} ${this.serverAddress}`
        }
      }

      const responseJson = await response.json()
      console.log('----------------------------')
      console.log(responseJson)
      console.log('----------------------------')
      return responseJson
    } catch(err) {
      throw { ...err }
    }
  }


  GetUsers = () => {
    return this.basicFetch(this.urls.GET_USERS, {
      method: 'GET'
    })
  }

这是我的 routes.js 文件

import { fetchApiTestAction } from './actions/fetchApiTestAction'



const routes = [

  {
    path: '/',
    exact: true,
    component: Home,
    fetchInitialData: fetchApiTestAction()
  },
  {
    path: '/about',
    component: About
  },
  {
    path: '/contact',
    component: Contact
  },

]

这是我的 server.js 文件

app.get('/*', (req, res, next) => {

  const activeRoute = routes.find( route => matchPath(req.url, route) ) || {}

  const _promise = activeRoute.fetchInitialData 
    ? activeRoute.fetchInitialData()
    : Promise.resolve()

  _promise.then( () => {

    const store = configureStore()
    const markup = renderToString(

      <StaticRouter location={req.url} context={{}}>
        <Provider store={store}>
          <App />
        </Provider>
      </StaticRouter>
    )

    const initialBrowserTabText = 'hi there from home page...'
    const initialState = store.getState() || {}

    const _template = template( initialBrowserTabText, initialState, markup )

    res.send(_template)
  }).catch(err => {
    console.log(err)
  })
})

到目前为止,我还没有遇到过这种问题。当我 console.log(dispatch) 在我的动作创建者内部(在 return 部分之前)时,它是未定义的。我应该说这是我的终端向我显示的内容:

Server is listening on port 8000...
----------------------------
{ page: 1,
  per_page: 3,
  total: 12,
  total_pages: 4,
  data: 
   [ { id: 1,
       first_name: 'George',
       last_name: 'Bluth',
       avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/calebogden/128.jpg' },
     { id: 2,
       first_name: 'Janet',
       last_name: 'Weaver',
       avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg' },
     { id: 3,
       first_name: 'Emma',
       last_name: 'Wong',
       avatar: 'https://s3.amazonaws.com/uifaces/faces/twitter/olegpogodaev/128.jpg' } ] }
----------------------------
TypeError: dispatch is not a function
    at eval (webpack-internal:///./src/js/actions/fetchApiTestAction.js:17:7)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

这说明我是从api获取数据,但是为什么dispatch不是一个函数呢?

【问题讨论】:

  • 为什么它首先是一个函数?你甚至在配置 redux-store 之前就在运行 fetchInitialData...dispatch 是 redux-store 的一个属性,如果你没有 redux-store,那么你不能 dispatch.. . 另外,请注意 activeRoute.fetchInitialData 不是 thunk... 如果是 thunk,它将被调度。

标签: javascript reactjs redux react-redux redux-thunk


【解决方案1】:

除非您在调用 fetchInitialData 时传递 redux-store dispatch 属性,否则这将不起作用......像这样:

  const _promise = activeRoute.fetchInitialData 
    ? activeRoute.fetchInitialData(store.dispatch)
    : Promise.resolve()

真正的问题是你的 redux-store 甚至不存在,因为你是在承诺完成后配置它......所以这是你必须解决的其他问题。

【讨论】:

  • 首先,感谢您的回复,但是我如何配置我的商店,以便在服务器需要调度操作以从端点获取数据时它可用于服务器端? ? fetchInitialData 最终出现在我的 service.js 配置文件中,这怎么可能在我的 service.js 文件中实例化存储?怎么可能?
  • 你是杰作,照顾好自己,非常感谢你回答我该死的正确答案。爱你...
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-07
  • 1970-01-01
相关资源
最近更新 更多