调度不是服务器端渲染中的功能
Dispatch is not a function in Server Side Rendering
我对 redux-thunk 有疑问,它只是没有将调度传递给我的 action creator。我正在记录它,但它仍然未定义:
这是我的动作创作者:
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.jsclass
// 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)
在我的 action creator 内部时(在 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 不是一个函数?
除非你在调用 fetchInitialData
时传递 redux-store dispatch
属性,否则这将不起作用......像这样的东西:
const _promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(store.dispatch)
: Promise.resolve()
真正的问题是你的 redux-store 那时甚至不存在,因为你是在 promise 完成后配置它的......所以这是你必须解决的其他问题。
我对 redux-thunk 有疑问,它只是没有将调度传递给我的 action creator。我正在记录它,但它仍然未定义:
这是我的动作创作者:
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.jsclass
// 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)
在我的 action creator 内部时(在 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 不是一个函数?
除非你在调用 fetchInitialData
时传递 redux-store dispatch
属性,否则这将不起作用......像这样的东西:
const _promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(store.dispatch)
: Promise.resolve()
真正的问题是你的 redux-store 那时甚至不存在,因为你是在 promise 完成后配置它的......所以这是你必须解决的其他问题。