【发布时间】:2019-05-15 23:27:34
【问题描述】:
我的 Redux reducer 无法正确更新状态时遇到问题。
这是我在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;
}
}
getAccounts 操作中的 dispatch(setAccountsLoading) 未正确更新 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);
有人知道为什么我的getAccounts 操作中的dispatch(setAccountsLoading) 没有正确更新加载状态吗?
【问题讨论】:
-
只需将
dispatch(setAccountsLoading);替换为dispatch(setAccountsLoading()); -
哇,真不敢相信我错过了……这确实是问题所在。非常感谢@VassilisPallas!
标签: javascript reactjs redux