admin管理员组文章数量:1405392
I am having an issue with my ponent that should fetch accounts.
I have a useEffect
hook to run the request but only runs when I refresh.
The useEffect
hook runs my console.log
s, but doesn't kick off the api request until I manually refresh.
The general flow of the app is, once you log in, then kick off the request to show your table of accounts.
Component:
import React, { useEffect } from 'react';
import { func, object } from 'prop-types';
import { connect } from "react-redux";
import { getAllPlaidAccountsById } from "../../actions/accountActions";
import styles from "./DebtTable.css";
const DebtTable = ({ auth: { user }, getAllPlaidAccountsById, account: accounts }) => {
useEffect(() => {
getAllPlaidAccountsById(user._id);
}, [getAllPlaidAccountsById]);
if (accounts && accounts !== null) {
return (
<table className={styles.accountsTable}>
<thead>
<tr>
<th>Account Name</th>
<th>Account Type</th>
<th>Interest Rate</th>
<th>Min Payment</th>
<th>Limit</th>
<th>Balance</th>
<th>Due Date</th>
</tr>
</thead>
<tbody>
{
accounts.accounts.map((account) => {
return account.map((acct, idx) => {
const leftBottomCell = idx === accounts.length - 1 ? 'leftBottomCell' : '';
const rightBottomCell = idx === accounts.length - 1 ? 'rightBottomCell' : '';
return (
<tr key={account.accountId}>
<td className={`${styles.accountName} ${styles[leftBottomCell]}`}>{acct.name}</td>
<td className={styles.accountType}>{acct.type}</td>
<td className={styles.interestRate}>-</td>
<td className={styles.minPayment}>-</td>
<td className={styles.accountLimit}>{`$${acct.balances.limit}`}</td>
<td className={styles.accountBalance}>{`$${acct.balances.current}`}</td>
<td className={`${styles.dueDate} ${styles[rightBottomCell]}`}>-</td>
</tr>
)
})
})
}
</tbody>
</table>
)
}
return null;
}
DebtTable.propTypes = {
getAllPlaidAccountsById: func.isRequired,
profile: object.isRequired,
auth: object.isRequired
};
const mapStateToProps = (state) => ({
profile: state.profile,
account: state.account
});
export default connect(mapStateToProps, { getAllPlaidAccountsById })(DebtTable);
Redux Action:
import axios from "axios";
import {
GET_ALL_PLAID_ACCOUNTS,
GET_ALL_PLAID_ACCOUNTS_ERROR
} from "./types";
export const getAllPlaidAccountsById = (userId) => async dispatch => {
try {
const res = await axios.get(`/api/accounts/${userId}`);
let creditCards = [];
res.data.map(account => {
if(account.type === 'credit') creditCards.push(account);
return null;
});
dispatch({
type: GET_ALL_PLAID_ACCOUNTS,
payload: creditCards
});
} catch (err) {
dispatch({
type: GET_ALL_PLAID_ACCOUNTS_ERROR,
payload: { msg: err }
});
}
};
Redux Reducer:
import {
GET_ALL_PLAID_ACCOUNTS,
GET_ALL_PLAID_ACCOUNTS_ERROR
} from '../actions/types';
const initialState = {
account: null,
accounts: [],
error: {}
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case GET_ALL_PLAID_ACCOUNTS:
return {
...state,
accounts: [payload, ...state.accounts],
loading: false
};
case GET_ALL_PLAID_ACCOUNTS_ERROR:
return {
...state,
error: payload,
loading: false
};
default:
return state;
}
}
I am having an issue with my ponent that should fetch accounts.
I have a useEffect
hook to run the request but only runs when I refresh.
The useEffect
hook runs my console.log
s, but doesn't kick off the api request until I manually refresh.
The general flow of the app is, once you log in, then kick off the request to show your table of accounts.
Component:
import React, { useEffect } from 'react';
import { func, object } from 'prop-types';
import { connect } from "react-redux";
import { getAllPlaidAccountsById } from "../../actions/accountActions";
import styles from "./DebtTable.css";
const DebtTable = ({ auth: { user }, getAllPlaidAccountsById, account: accounts }) => {
useEffect(() => {
getAllPlaidAccountsById(user._id);
}, [getAllPlaidAccountsById]);
if (accounts && accounts !== null) {
return (
<table className={styles.accountsTable}>
<thead>
<tr>
<th>Account Name</th>
<th>Account Type</th>
<th>Interest Rate</th>
<th>Min Payment</th>
<th>Limit</th>
<th>Balance</th>
<th>Due Date</th>
</tr>
</thead>
<tbody>
{
accounts.accounts.map((account) => {
return account.map((acct, idx) => {
const leftBottomCell = idx === accounts.length - 1 ? 'leftBottomCell' : '';
const rightBottomCell = idx === accounts.length - 1 ? 'rightBottomCell' : '';
return (
<tr key={account.accountId}>
<td className={`${styles.accountName} ${styles[leftBottomCell]}`}>{acct.name}</td>
<td className={styles.accountType}>{acct.type}</td>
<td className={styles.interestRate}>-</td>
<td className={styles.minPayment}>-</td>
<td className={styles.accountLimit}>{`$${acct.balances.limit}`}</td>
<td className={styles.accountBalance}>{`$${acct.balances.current}`}</td>
<td className={`${styles.dueDate} ${styles[rightBottomCell]}`}>-</td>
</tr>
)
})
})
}
</tbody>
</table>
)
}
return null;
}
DebtTable.propTypes = {
getAllPlaidAccountsById: func.isRequired,
profile: object.isRequired,
auth: object.isRequired
};
const mapStateToProps = (state) => ({
profile: state.profile,
account: state.account
});
export default connect(mapStateToProps, { getAllPlaidAccountsById })(DebtTable);
Redux Action:
import axios from "axios";
import {
GET_ALL_PLAID_ACCOUNTS,
GET_ALL_PLAID_ACCOUNTS_ERROR
} from "./types";
export const getAllPlaidAccountsById = (userId) => async dispatch => {
try {
const res = await axios.get(`/api/accounts/${userId}`);
let creditCards = [];
res.data.map(account => {
if(account.type === 'credit') creditCards.push(account);
return null;
});
dispatch({
type: GET_ALL_PLAID_ACCOUNTS,
payload: creditCards
});
} catch (err) {
dispatch({
type: GET_ALL_PLAID_ACCOUNTS_ERROR,
payload: { msg: err }
});
}
};
Redux Reducer:
import {
GET_ALL_PLAID_ACCOUNTS,
GET_ALL_PLAID_ACCOUNTS_ERROR
} from '../actions/types';
const initialState = {
account: null,
accounts: [],
error: {}
};
export default function(state = initialState, action) {
const { type, payload } = action;
switch (type) {
case GET_ALL_PLAID_ACCOUNTS:
return {
...state,
accounts: [payload, ...state.accounts],
loading: false
};
case GET_ALL_PLAID_ACCOUNTS_ERROR:
return {
...state,
error: payload,
loading: false
};
default:
return state;
}
}
Share
Improve this question
asked May 1, 2020 at 21:04
Chris McGlynnChris McGlynn
531 gold badge1 silver badge8 bronze badges
6
-
1
your effect has a needless dependency of
getAllPlaidAccountsById
and a missing dependency ofuser._id
– HMR Commented May 1, 2020 at 21:06 -
what do you mean needless, isn't
getAllPlaidAccountsById
necessary to be able to run? – Chris McGlynn Commented May 1, 2020 at 21:17 - You import it so it's static and will never change – HMR Commented May 1, 2020 at 21:26
-
I imported it for the
connect
function which maps it to props. Are you saying that its not need to do that? Im a little confused as to what you are saying. Also,user.id
is destructured from props, how is it missing? – Chris McGlynn Commented May 1, 2020 at 21:36 -
Ok, I see, you can add it to satisfy the linter but adding
user._id
is most important as it will run the effect when that changes. – HMR Commented May 1, 2020 at 21:39
1 Answer
Reset to default 3The second parameter to useEffect is an array of variables that control when the useEffect executes. When the value of a variable in the array changes, then the useEffect will re-run. See https://reactjs/docs/hooks-effect.html#tip-optimizing-performance-by-skipping-effects
It seems likely that you want to get the accounts whenever a user._id
changes, so you should pass an array containing that variable as the second argument to useEffect.
useEffect(() => {
getAllPlaidAccountsById(user._id);
}, [user._id]);
本文标签: javascriptuseEffect runs api request after I refresh the pageStack Overflow
版权声明:本文标题:javascript - useEffect runs api request after I refresh the page - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744877342a2629995.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论