根据文档,"没有中间件,Redux商店只支持同步数据流".我不明白为什么会这样.为什么容器组件不能调用异步API,然后调用dispatch
操作?
例如,想象一个简单的UI:字段和按钮.当用户按下按钮时,该字段将填充来自远程服务器的数据.
import * as React from 'react';
import * as Redux from 'redux';
import { Provider, connect } from 'react-redux';
const ActionTypes = {
STARTED_UPDATING: 'STARTED_UPDATING',
UPDATED: 'UPDATED'
};
class AsyncApi {
static getFieldValue() {
const promise = new Promise((resolve) => {
setTimeout(() => {
resolve(Math.floor(Math.random() * 100));
}, 1000);
});
return promise;
}
}
class App extends React.Component {
render() {
return (
<div>
<input value={this.props.field}/>
<button disabled={this.props.isWaiting} onClick={this.props.update}>Fetch</button>
{this.props.isWaiting && <div>Waiting...</div>}
</div>
); …
Run Code Online (Sandbox Code Playgroud) 现在有很多关于redux镇最新孩子的讨论,redux-saga/redux-saga.它使用生成器函数来监听/调度操作.
在我绕过它之前,我想知道redux-saga
使用redux-thunk
async/await时使用的优点/缺点而不是下面的方法.
组件可能看起来像这样,像往常一样调度动作.
import { login } from 'redux/auth';
class LoginForm extends Component {
onClick(e) {
e.preventDefault();
const { user, pass } = this.refs;
this.props.dispatch(login(user.value, pass.value));
}
render() {
return (<div>
<input type="text" ref="user" />
<input type="password" ref="pass" />
<button onClick={::this.onClick}>Sign In</button>
</div>);
}
}
export default connect((state) => ({}))(LoginForm);
Run Code Online (Sandbox Code Playgroud)
然后我的行为看起来像这样:
// auth.js
import request from 'axios';
import { loadUserData } from './user';
// define constants
// define initial state
// export default reducer …
Run Code Online (Sandbox Code Playgroud) 据我所知并纠正我,如果我错了,redux-thunk是一个中间件,它可以帮助我们在动作本身中调度异步函数和调试值,而当我使用redux-promise时,我无法创建异步函数而不实现自己的机制为Action抛出仅调度普通对象的异常.
这两个包之间的主要区别是什么?在单页反应应用中使用这两个包还是坚持使用redux-thunk有什么好处就足够了?
我已经插入了一个中间件,redux-thunk,我想添加另一个,redux-logger.
如何配置它以便我的应用程序使用两个中间件?我试过传递一组[ReduxThunk, logger]
但是没有用.
码:
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import ReduxThunk from 'redux-thunk';
import logger from 'redux-logger';
import App from './components/app';
import reducers from './reducers';
require('./style.scss');
const createStoreWithMiddleware = applyMiddleware(ReduxThunk)(createStore);
ReactDOM.render(
<Provider store={createStoreWithMiddleware(reducers)}>
<App />
</Provider>,
document.querySelector('#app')
);
Run Code Online (Sandbox Code Playgroud) 我目前正在尝试概念化如何处理在另一个组件中的调度之后基于数据更改在组件中调度操作.
采取这种情况:
dispatch(someAjax)
- >状态更新中的属性.
在此之后,我需要另一个依赖于此相同属性的组件来知道已更新并根据新值调度操作.
而不是使用某种类型的value.on(change...
解决方案,处理这种类型的动作'级联'的首选方法是什么?
在我开始组合我的Redux减速器之前,我的应用程序工作正常.但是当我合并时,initialState和reducer键会混淆.
function flash(state = [], action) {
switch (action.type) {
case FLASH_MESSAGE_UPDATED:
return _.extend({}, state, { flash: action.flash })
default:
return state
}
}
function events(state = [], action) {
switch (action.type) {
case EVENTS_UPDATED:
return _.extend({}, state, { events: action.pathway_events })
default:
return state
}
}
export default combineReducers({
events,
flash
})
Run Code Online (Sandbox Code Playgroud)
这会导致功能损坏和控制台错误:
Unexpected keys "one", "two" found in initialState argument passed to createStore. Expected to find one of the known reducer keys instead: "events", "flash". Unexpected …
商店.ts
export const store = configureStore({
reducer: {
auth: authReducer
},
middleware: [],
});
export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;
Run Code Online (Sandbox Code Playgroud)
钩子.ts
export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
Run Code Online (Sandbox Code Playgroud)
authSlice.ts(导致问题的函数)
export const fetchUser = createAsyncThunk(
'users/fetchByTok',
async () => {
const res = await getUser();
return res.data;
}
)
Run Code Online (Sandbox Code Playgroud)
授权ts
const Auth = ({ component, isLogged }: {component: any, isLogged: boolean}) => {
const dispatch = useAppDispatch();
useEffect(() => …
Run Code Online (Sandbox Code Playgroud) //为了清晰而编辑
我正在尝试用redux thunk链接调度
function simple_action(){
return {type: "SIMPLE_ACTION"}
}
export function async_action(){
return function(dispatch, getState){
return dispatch(simple_action).then(()=>{...});
}
}
Run Code Online (Sandbox Code Playgroud)
如何让调度从商店返回承诺?
进一步来说:
我可能只是在这里不了解一些东西,但是在所有的例子中redux-thunk
,它们都会调用一个单独的异步事件(如fetch
),这显然会返回一个Promise
.
我特别想要的是当我向商店发送一个动作时:如何确保商店在上述功能发生任何其他事件之前完全处理了该动作action_creator()
.
理想情况下,我希望商店能够返回某种承诺,但我不明白这是怎么回事?
我有一个React应用程序,我需要使用Redux进行ajax调用(以便学习)到在线服务(异步).
这是我的商店:
import { createStore, applyMiddleware } from 'redux';
import thunk from 'redux-thunk';
import duedates from './reducers/duedates'
export default applyMiddleware(thunk)(createStore)(duedates);
Run Code Online (Sandbox Code Playgroud)
这是行动:
import rest from '../Utils/rest';
export function getDueDatesOptimistic(dueDates){
console.log("FINISH FETCH");
console.log(dueDates);
return {
type: 'getDueDate',
dueDates
}
}
export function waiting() {
console.log("IN WAIT");
return {
type: 'waiting'
}
}
function fetchDueDates() {
console.log("IN FETCH");
return rest({method: 'GET', path: '/api/dueDates'});
}
export function getDueDates(dispatch) {
console.log("IN ACTION");
return fetchDueDates().done(
dueDates => dispatch(getDueDatesOptimistic(dueDates.entity._embedded.dueDates))
)
}
Run Code Online (Sandbox Code Playgroud)
这是减速器:
export default (state = {}, …
Run Code Online (Sandbox Code Playgroud) action.js
export function getLoginStatus() {
return async(dispatch) => {
let token = await getOAuthToken();
let success = await verifyToken(token);
if (success == true) {
dispatch(loginStatus(success));
} else {
console.log("Success: False");
console.log("Token mismatch");
}
return success;
}
}
Run Code Online (Sandbox Code Playgroud)
component.js
componentDidMount() {
this.props.dispatch(splashAction.getLoginStatus())
.then((success) => {
if (success == true) {
Actions.counter()
} else {
console.log("Login not successfull");
}
});
}
Run Code Online (Sandbox Code Playgroud)
但是,当我用async/await编写component.js代码时,我得到此错误:
Possible Unhandled Promise Rejection (id: 0): undefined is not a function (evaluating 'this.props.dispatch(splashAction.getLoginStatus())')
component.js
async componentDidMount() {
let success = …
Run Code Online (Sandbox Code Playgroud) reactjs react-native redux-thunk react-redux ecmascript-2017
redux-thunk ×10
reactjs ×9
redux ×8
javascript ×4
react-redux ×3
asynchronous ×2
middleware ×1
react-native ×1
redux-saga ×1