我的Redux减速器存在问题,无法正确更新状态。
这是我在accountActions.js
文件中的动作。
// Get all accounts for specific user
export const getAccounts = () => dispatch => {
dispatch(setAccountsLoading); // NOT WORKING
axios
.get("/api/plaid/accounts")
.then(res =>
dispatch({
type: GET_ACCOUNTS,
payload: res.data
})
)
.catch(err =>
dispatch({
type: GET_ACCOUNTS,
payload: null
})
);
};
// Accounts loading
export const setAccountsLoading = () => {
return {
type: ACCOUNTS_LOADING
};
};
这是我的actionsReducers.js
文件。
import {
GET_ACCOUNTS,
ACCOUNTS_LOADING,
} from "../actions/types";
const initialState = {
accounts: [],
loading: false
};
export default function(state = initialState, action) {
switch (action.type) {
case ACCOUNTS_LOADING:
return {
...state,
loading: true
};
case GET_ACCOUNTS:
return {
...state,
accounts: action.payload,
loading: false
};
default:
return state;
}
}
我的dispatch(setAccountsLoading)
操作中的getAccounts
无法正确更新loading
状态。
在我的Dashboard.js
组件中,我叫getAccounts
。基于loading
状态,我希望显示一条“正在加载...”消息。如果getAccounts
返回的帐户为零,我希望显示一条消息以添加第一个帐户。否则,如果getAccounts
返回一个或多个帐户,我希望显示仪表板。
这是我的Dashboard.js
组件。
import React, { Component } from "react";
import PlaidLink from "react-plaid-link";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { logoutUser } from "../../actions/authActions";
import {
getAccounts,
addAccount
} from "../../actions/accountActions";
import Transactions from "./Transactions";
class Dashboard extends Component {
componentDidMount() {
this.props.getAccounts();
}
// Logout
onLogoutClick = e => {
e.preventDefault();
this.props.logoutUser();
};
// Add account
handleOnSuccess = (token, metadata) => {
const plaidData = {
public_token: token,
metadata: metadata
};
this.props.addAccount(plaidData);
};
render() {
const { accounts, loading } = this.props.plaid;
let dashboardContent;
// Loading state is always false (setAccountsLoading not being called properly)
if (loading) {
dashboardContent = <p>Loading...</p>;
} else if (accounts === null || Object.keys(accounts).length === 0) {
dashboardContent = (
<div>
<h4>
<b>Welcome,</b> User
</h4>
<p className="flow-text grey-text text-darken-1">
To get started, link your first bank account below
</p>
<PlaidLink
clientName="Mosaic"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
env="sandbox"
product={["auth", "transactions"]}
publicKey="0c3ff69a2efea552189de8b7fbbc0f"
onSuccess={this.handleOnSuccess}
style={{
width: "185px",
letterSpacing: "1.5px",
borderRadius: "3px",
marginTop: "1rem"
}}
>
Link Account
</PlaidLink>
<button
style={{
width: "185px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
onClick={this.onLogoutClick}
className="btn btn-large waves-effect waves-light hoverable red accent-3"
>
Logout
</button>
</div>
);
} else {
dashboardContent = <Transactions accounts={accounts} />;
}
return (
<div className="container">
<div className="row">
<div className="col s12 center-align">{dashboardContent}</div>
</div>
</div>
);
}
}
Dashboard.propTypes = {
logoutUser: PropTypes.func.isRequired,
getAccounts: PropTypes.func.isRequired,
addAccount: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
plaid: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
plaid: state.plaid
});
export default connect(
mapStateToProps,
{ logoutUser, getAccounts, addAccount }
)(Dashboard);
加载值始终为false(在任何时候都不会切换为true)。在我的信息中心中,如果我console.log(loading)
,我看到两条消息表明loading
为假(一条消息触发getAccounts
,另一条消息getAccounts
完成)。
我当前使用的一种(不正确的)解决方法是从组件本身内部调用setAccountsLoading
。当我这样做时,加载值将设置为true
,直到getAccounts
完成为止(这会将loading
设置为false)。
import React, { Component } from "react";
import PlaidLink from "react-plaid-link";
import PropTypes from "prop-types";
import { connect } from "react-redux";
import { logoutUser } from "../../actions/authActions";
import {
getAccounts,
setAccountsLoading,
addAccount
} from "../../actions/accountActions";
import Transactions from "./Transactions";
class Dashboard extends Component {
componentDidMount() {
this.props.getAccounts();
// Temporary workaround; this has the desired outcome
this.props.setAccountsLoading();
}
// Logout
onLogoutClick = e => {
e.preventDefault();
this.props.logoutUser();
};
// Add account
handleOnSuccess = (token, metadata) => {
const plaidData = {
public_token: token,
metadata: metadata
};
this.props.addAccount(plaidData);
};
render() {
const { accounts, loading } = this.props.plaid;
let dashboardContent;
if (loading) {
dashboardContent = <p>Loading...</p>;
} else if (accounts === null || Object.keys(accounts).length === 0) {
dashboardContent = (
<div>
<h4>
<b>Welcome,</b> User
</h4>
<p className="flow-text grey-text text-darken-1">
To get started, link your first bank account below
</p>
<PlaidLink
clientName="Mosaic"
className="btn btn-large waves-effect waves-light hoverable blue accent-3"
env="sandbox"
product={["auth", "transactions"]}
publicKey="0c3ff69a2efea552189de8b7fbbc0f"
onSuccess={this.handleOnSuccess}
style={{
width: "185px",
letterSpacing: "1.5px",
borderRadius: "3px",
marginTop: "1rem"
}}
>
Link Account
</PlaidLink>
<button
style={{
width: "185px",
borderRadius: "3px",
letterSpacing: "1.5px",
marginTop: "1rem"
}}
onClick={this.onLogoutClick}
className="btn btn-large waves-effect waves-light hoverable red accent-3"
>
Logout
</button>
</div>
);
} else {
dashboardContent = <Transactions accounts={accounts} />;
}
return (
<div className="container">
<div className="row">
<div className="col s12 center-align">{dashboardContent}</div>
</div>
</div>
);
}
}
Dashboard.propTypes = {
logoutUser: PropTypes.func.isRequired,
getAccounts: PropTypes.func.isRequired,
addAccount: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
plaid: PropTypes.object.isRequired
};
const mapStateToProps = state => ({
auth: state.auth,
plaid: state.plaid
});
export default connect(
mapStateToProps,
{ logoutUser, getAccounts, setAccountsLoading, addAccount }
)(Dashboard);
有人知道为什么我的dispatch(setAccountsLoading)
操作中的getAccounts
没有正确更新加载状态吗?
答案 0 :(得分:0)
如Vassilis Pallas在评论中所述,函数调用后的括号缺失,因此您应该使用$.ajax({
url: '/API/Video/GetVideoInfo/25',
dataType: 'application/json',
complete: function (data) {
var json = JSON.parse(data.responseText);
alert(json["Views"]);
},
});
而不是dispatch(setAccountsLoading())
。
在另一个主题中,我想推荐Redux Promise Middleware来简化Redux中的请求使用,您只需要将请求promise分配为有效负载,此包将为您处理,分配Pending,Fulfilled和拒绝的操作取决于传递的Promise的分辨率。
这帮助我大大简化了异步Redux代码,尤其是与Type to Reducer中建议的reducers documentation of Redux Promise Middleware之类的对象配对时。