簡體   English   中英

UseEffect 在使用 context 作為依賴並且更新 context 時不會觸發

[英]UseEffect does not trigger when using context as dependency and context is updated

我正在為組件的 state 使用自定義掛鈎。我使用 useEffect 更新依賴於上下文的 state。 當我更新上下文時,我的 useEffect 不會觸發。 我可以通過控制台日志和 React 開發工具看到正在更新的上下文值。

這是自定義掛鈎

export const useFilteredTrans = (
  type: string,
  transactions: Transaction[] | undefined
): Transaction[] | null => {
  const [filteredTrans, setFilteredTrans] = useState<Transaction[] | null>(null)
  useEffect(() => {
    if (transactions && transactions.length > 0) {
      const filtered = transactions.filter(
        (transaction) => transaction.type === type
      )
      setFilteredTrans(filtered)
    }
  }, [transactions])
  return filteredTrans

這是使用上下文和自定義掛鈎的組件:

export const Expenses = () => {
  const {
    currentAccount: { transactions },
  } = useContext(AccountContext)
  const expenses = useFilteredTrans('e', transactions)

  return (
    <div>
      <Module>
        <div className='mb-4 flex justify-between'>
          <h1>Expenses</h1>
          <ShowAddModalButton modalType='e' entityType='e' />
        </div>
        {expenses
          ? expenses.map((expenseItem) => {
              const { id, date, expense, credit, amount } = expenseItem
              return (
                <div className='grid grid-cols-5 gap-3' key={id}>
                  <p className='col-span-2'>{fmtDateString(date)}</p>
                  <p>{expense?.name}</p>
                  <p className='text-right'>{credit ? '+ $' : '- $'} </p>
                  <p className='text-right'>{amount}</p>
                </div>
              )
            })
          : null}
      </Module>
    </div>
  )
}

上下文正在通過一個從服務器獲取新事務並將其添加到正在呈現的當前帳戶的縮減器進行更新。

    case 'ADD_EXPENSE': {
      const account = state.currentAccount
      account.transactions?.unshift(action.payload)
      return { ...state, currentAccount: account, isLoading: false }
    }

當我添加新費用時,交易會在上下文中更新,但帶有 state 的自定義掛鈎不會更新。 我是否遺漏了一段代碼或我對 useEffect 掛鈎的理解完全消失了?

不確定我是否理解完整的邏輯,但似乎 reducer 可能會在return之前改變現有的 state 。 作為嘗試也許嘗試:

case 'ADD_EXPENSE': {
  const { transactions } = state.currentAccount;
  const newtransactions = transactions
    ? [action.payload, ...transactions]
    : [action.payload];
  return {
    ...state,
    currentAccount: { ...state.currentAccount, transactions: newtransactions },
    isLoading: false,
  };
};

直接修改原始 state 並不是真的“安全”,因為unshift就像push方法一樣,就地修改原始數組:

const account = state.currentAccount
account.transactions?.unshift(action.payload)
return { ...state, currentAccount: account, isLoading: false }

嘗試復制開頭的 state:

const copiedState = JSON.parse(JSON.stringify(state));
const account = copiedState.currentAccount;
account.transactions?.unshift(action.payload);
return copiedState;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM