javascript 为什么这段代码在页面刷新之前一直有效?

3qpi33ja  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(154)

我为我的无知道歉,但是我不明白为什么这段代码要在页面刷新后才能工作。主要目的是在我获取的response.json上使用array.reduce方法,以便我可以获得组件中显示的所有json []. amount元素的滚动总和。这段代码要在页面刷新后才能工作,然后它会说:未捕获的类型错误:无法在Balance(Balance. js:27:1)读取null的属性(读取"reduce")。我至少知道我在状态方面做错了什么。
Balance.js组件:

import { useEffect } from "react";
import {useBalancesContext} from '../hooks/useBalancesContext'
import { useAuthContext } from '../hooks/useAuthContext'

function Balance(){
  const {balances, dispatch} = useBalancesContext()
  const {user} = useAuthContext()
  
  useEffect(() => {
    const addBalances = async () => {
      const response = await fetch("http://localhost:4000/api/balances", {
        headers: {
          'Authorization': `Bearer ${user.token}`
        }
      });
      const json = await response.json();

      if (response.ok) {
        dispatch({type: 'SET_BALANCES', payload: json})
      }
      }

    if (user) {
      addBalances();
    }
  }, [dispatch, user]);
  const newBalance = balances.reduce((accumulator, currentValue) => accumulator + currentValue.amount, 0)
  return (
    <div className="header">
      <strong>Available Balance: ${newBalance}</strong>
    </div>
    )
  }

export default Balance;

BalanceContext.js:

import { createContext, useReducer } from "react";

export const BalancesContext = createContext();

export const balancesReducer = (state, action) => {
  switch (action.type) {
      case 'SET_BALANCES':
      return {
        balances: action.payload
      }
  /*    case 'SUM_BALANCES': 
       return { 
        balances: state.balances.amount.reduce((accumulator, currentValue) => accumulator + currentValue.amount, 0)
       } */
      case 'CREATE_BALANCE':
        return {
          balances: [action.payload, ...state.balances]
        }
      case 'DELETE_BALANCE':
        return {
          balances: state.balances.filter((b) => b._id !== action.payload._id)
        }
        default:
          return state
  }
}

export const BalancesContextProvider = ({ children }) => {
  const [state, dispatch] = useReducer(balancesReducer, {
    balances: null
  })

  return (
    <BalancesContext.Provider value={{...state, dispatch}}>
      {children}
    </BalancesContext.Provider>
  )
};

我试过在函数内部使用array.reduce方法,但是我无法访问Balance组件内部的newBalance值。我也试过在reducer中使用array.reduce,但是我也不确定我的方法是否正确。

ffdz8vbo

ffdz8vbo1#

balances初始为null,因此在加载页面时可能未设置其值。
使用.reduce()计算值的一个好方法是使用useMemo挂接:

import { useMemo } from 'react';

  const newBalance = useMemo(() => {
    if (!balances) return 0;
    return balances.reduce(
      (accumulator, currentValue) => accumulator + currentValue.amount,
      0
    );
  }, [balances]);

这将告知React仅在balances更改时计算newBalance,如果balances尚未设置,则将返回0

相关问题