如何从节点服务器端使用redux-thunk? [英] How to use redux-thunk from node server side?
问题描述
(来自 https://redux.js.org/advanced/async-actions <的代码)
代码设置了Redux存储,然后使用一些操作调用存储上的dispatch。商店使用redux-thunk来管理异步API调用。
The code setups a redux store and then calls dispatch on the store with some actions. The store use redux-thunk to manage async API calls.
这是index.js
Here is the index.js
import reduxThunk from 'redux-thunk'
const { thunkMiddleware } = reduxThunk;
import redux from 'redux';
const { createStore } = redux;
const { applyMiddleware } = redux;
import { selectSubreddit, fetchPosts } from './actions.js'
import rootReducer from './reducers.js'
const store = createStore(
rootReducer,
applyMiddleware(thunkMiddleware)
);
store.dispatch(selectSubreddit('reactjs'));
store.dispatch(fetchPosts('reactjs')).then(() => console.log(store.getState()));
运行 node index.js
<后出现错误/ p>
Error after running node index.js
(node:19229) ExperimentalWarning: The ESM module loader is experimental.
applyMiddleware [Function: applyMiddleware]
/home/code/redux/tutorial_async_actions/node_modules/redux/lib/redux.js:648
return middleware(middlewareAPI);
^
TypeError: middleware is not a function
at /home/code/redux/tutorial_async_actions/node_modules/redux/lib/redux.js:648:16
at Array.map (<anonymous>)
at /home/code/redux/tutorial_async_actions/node_modules/redux/lib/redux.js:647:31
at createStore (/home/code/redux/tutorial_async_actions/node_modules/redux/lib/redux.js:85:33)
at file:///home/code/redux/tutorial_async_actions/index.js:18:15
at ModuleJob.run (internal/modules/esm/module_job.js:110:37)
at async Loader.import (internal/modules/esm/loader.js:164:24)
我该怎么做才能使它运行?我认为这与ES6和模块有关,但我遇到了麻烦。 ::(
What do I do to get this to run? I think this has something to do with ES6 and modules but I'm stuck... :(
我已经在执行此操作(如此答案)
I am already doing this (as suggested by this answer)
import redux from 'redux';
const { createStore, applyMiddleware } = redux;
(我可以使用create-react-app来使它工作……但是我更愿意
(I could get this to work using create-react-app ... but I would prefer to get this working without webpack et al)
在其余代码下面供参考。
Below the remaining code for reference.
此处的操作
export const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT'
export function selectSubreddit(subreddit) {
return {
type: SELECT_SUBREDDIT,
subreddit
};
}
export const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT'
function invalidateSubreddit(subreddit) {
return {
type: INVALIDATE_SUBREDDIT,
subreddit
};
}
export const REQUEST_POSTS = 'REQUEST_POSTS'
function requestPosts(subreddit) {
return {
type: REQUEST_POSTS,
subreddit
}
}
export const RECEIVE_POSTS = 'RECEIVE_POSTS'
function receivePosts(subreddit, json) {
return {
type: RECEIVE_POSTS,
subreddit,
posts: json.data.children.map(child => child.data),
receivedAt: Date.now()
}
}
export function fetchPosts(subreddit) {
return function (dispatch) {
dispatch(requestPosts(subreddit));
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then(
response => response.json(),
error => console.log('An error occurred.', error)
)
.then(json =>
dispatch(receivePosts(subreddit, json))
)
}
}
减速器
import redux from 'redux';
const { combineReducers } = redux;
import {
SELECT_SUBREDDIT,
INVALIDATE_SUBREDDIT,
REQUEST_POSTS,
RECEIVE_POSTS
} from './actions.js';
function selectedSubreddit(state = 'reactjs', action) {
switch (action.type) {
case SELECT_SUBREDDIT:
return action.subreddit
default:
return state
}
}
function posts(
state = {
isFetching: false,
didInvalidate: false,
items: []
},
action
) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
return Object.assign({}, state, { didInvalidate: true })
case REQUEST_POSTS:
return Object.assign({}, state, { isFetching: true, didInvalidate: false });
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false, didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
});
default:
return state;
}
}
function postsBySubreddit(state = {}, action) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
case RECEIVE_POSTS:
case REQUEST_POSTS:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
});
default:
return state
}
}
const rootReducer = combineReducers({
postsBySubreddit,
selectedSubreddit
});
export default rootReducer;
此处package.json
Here package.json
{
"name": "redux_async_actions",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"type": "module",
"dependencies": {
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
}
}
推荐答案
(我最初问的问题是我丢失了登录名)
(I originally asked the question but I lost my login)
我使用节点模块系统来工作(即使用require函数) 。 ES6导出/导入应该可以工作,但是我想我尝试使用的一个或其他模块(redux,redux-thunk)在ES6导出/导入中不能很好地发挥作用。
I got this to work using the node module system (i.e. using the function require). The ES6 export / import should work but I guess one or other of the modules I am trying to use (redux, redux-thunk) does not play nicely with ES6 export / import.
基本上,我将 export
语句转换为 exports。
语句
Essentially I converted the export
statements to exports.
statements
export function(...){...}
=> exports.myFunction = function(...){。 。}
然后我将 import
语句转换为需要
语句。
And the I converted import
statements to require
statements.
从'./somefile.js'
导入{myFunction} => const模块= require('./ somefile.js')
import {myFunction} from './somefile.js'
=> const module = require('./somefile.js')
在下面的代码中
index.js
const redux = require('redux');
const { createStore, applyMiddleware } = redux;
const ReduxThunk = require('redux-thunk').default
const actions = require('./actions.js');
const { selectSubreddit, fetchPosts } = actions;
const rootReducer = require('./reducers.js');
const store = createStore(
rootReducer.rootReducer,
applyMiddleware(ReduxThunk)
);
store.dispatch(selectSubreddit('reactjs'));
store.dispatch(fetchPosts('reactjs')).then(() => console.log(store.getState()));
actions.js
actions.js
const fetch = require('cross-fetch');
const SELECT_SUBREDDIT = 'SELECT_SUBREDDIT'
exports.SELECT_SUBREDDIT = SELECT_SUBREDDIT
function selectSubreddit(subreddit) {
return {
type: SELECT_SUBREDDIT,
subreddit
};
}
exports.selectSubreddit = selectSubreddit;
const INVALIDATE_SUBREDDIT = 'INVALIDATE_SUBREDDIT'
exports.INVALIDATE_SUBREDDIT = INVALIDATE_SUBREDDIT
function invalidateSubreddit(subreddit) {
return {
type: INVALIDATE_SUBREDDIT,
subreddit
};
}
const REQUEST_POSTS = 'REQUEST_POSTS'
exports.REQUEST_POSTS = REQUEST_POSTS
function requestPosts(subreddit) {
return {
type: REQUEST_POSTS,
subreddit
}
}
const RECEIVE_POSTS = 'RECEIVE_POSTS'
exports.RECEIVE_POSTS = RECEIVE_POSTS
function receivePosts(subreddit, json) {
return {
type: RECEIVE_POSTS,
subreddit,
posts: json.data.children.map(child => child.data),
receivedAt: Date.now()
}
}
function fetchPosts(subreddit) {
return function (dispatch) {
dispatch(requestPosts(subreddit));
return fetch(`https://www.reddit.com/r/${subreddit}.json`)
.then(
response => response.json(),
error => console.log('An error occurred.', error)
)
.then(json =>
dispatch(receivePosts(subreddit, json))
)
}
}
exports.fetchPosts = fetchPosts;
reducers.js
reducers.js
const redux = require('redux');
const { combineReducers } = redux;
const actions = require('./actions.js');
const {
SELECT_SUBREDDIT,
INVALIDATE_SUBREDDIT,
REQUEST_POSTS,
RECEIVE_POSTS
} = actions;
function selectedSubreddit(state = 'reactjs', action) {
switch (action.type) {
case SELECT_SUBREDDIT:
return action.subreddit
default:
return state
}
}
function posts(
state = {
isFetching: false,
didInvalidate: false,
items: []
},
action
) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
return Object.assign({}, state, { didInvalidate: true })
case REQUEST_POSTS:
return Object.assign({}, state, { isFetching: true, didInvalidate: false });
case RECEIVE_POSTS:
return Object.assign({}, state, {
isFetching: false, didInvalidate: false,
items: action.posts,
lastUpdated: action.receivedAt
});
default:
return state;
}
}
function postsBySubreddit(state = {}, action) {
switch (action.type) {
case INVALIDATE_SUBREDDIT:
case RECEIVE_POSTS:
case REQUEST_POSTS:
return Object.assign({}, state, {
[action.subreddit]: posts(state[action.subreddit], action)
});
default:
return state
}
}
const rootReducer = combineReducers({
postsBySubreddit,
selectedSubreddit
});
exports.rootReducer = rootReducer;
package.json(注意,程序包没有 type: module ,
)
package.json (notice package does not have "type": "module",
)
{
"name": "basic_example_only_node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"cross-fetch": "^3.0.4",
"redux": "^4.0.5",
"redux-thunk": "^2.3.0"
}
}
这篇关于如何从节点服务器端使用redux-thunk?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!