reactjs 功能组件中的React Redux阵列状态更改不工作

1wnzp6jl  于 2023-01-08  发布在  React
关注(0)|答案(5)|浏览(143)

即使更改了阵列状态,useEffect也不起作用。
我首先通过dispatch(addTransaction(10))将金额添加到事务数组中。
然后我想通过调度dispatch(countTotal(transactions))来计算数组的和。
我不知道哪里出了问题。

import logo from './logo.svg';
import './App.css';
import { useState, useEffect } from 'react'

import { addTransaction } from './actions/transActions';
import { countTotal } from './actions/countActions';

import { shallowEqual, useDispatch, useSelector } from 'react-redux';

function App() {
  const transactions = useSelector(state => {
   return state.trans.transactions

});

  const count = useSelector(state => state.count.total);
  
  const dispatch = useDispatch()

  useEffect(() => {
    console.log("useEffect", transactions)
    dispatch(countTotal(transactions))
  }, [transactions])

  console.log('transactions', transactions)

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
       <h1>{count}</h1>
       <br></br>
       <div>
       <button style={{width:90, height:60, fontSize: 40, backgroundColor: 'teal', border: '0px', color: 'white'}} onClick={() => {
        dispatch(addTransaction(10))
        }} type="button"> + 10</button> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
       <button style={{width:90, height:60, fontSize: 40, backgroundColor: 'indianred', border: '0px', color: 'white'}}  onClick={() => dispatch(addTransaction(-10))} type="button"> - 10 </button>

       </div>
       </header>

    </div>
  );
}

export default App;

添加交易代码:

export const addTransaction = (amount) => (dispatch) => {
    dispatch({
        type: "ADD_TRANSACTION",
        payload: amount,
      })
}

减速器代码:

const initialState = {
    transactions : []
  };
  
  export default function(state = initialState, action) {
    switch (action.type) {
      case "ADD_TRANSACTION":
        console.log('ADD_TRANS', action.payload)
        let trans = state.transactions;
        trans.push(action.payload)

        return {
          ...state,
          transactions: trans
        };
      default:
       return state;
    }
  }

一切都很好。甚至dispatch(countTotal(transactions))也在工作。除了当我在使用效果中触发它时,它不工作。

s4n0splo

s4n0splo1#

通过更改代码的reducer部分修复了该问题,因为阵列正在更新,但检测到状态变化。

const initialState = {
    transactions : []
  };
  
  export default function(state = initialState, action) {
    switch (action.type) {
      case "ADD_TRANSACTION":
        console.log('ADD_TRANS', action.payload)
        let trans = [...state.transactions, action.payload]

        return {
          ...state,
          transactions: trans
        };
      default:
       return state;
    }
  }

这解决了问题。

txu3uszq

txu3uszq2#

你不能在“bare Redux”中的Reducer中使用push,因为它正在改变状态,但是状态应该被认为是不可变的。你也不应该使用bare Redux,而是应该使用Redux Toolkit,它使用了一个库,使得使用push和任何其他改变代码成为可能,而没有任何类似错误的风险。

xpszyzbs

xpszyzbs3#

你的addTransaction动作构建器出了问题。它应该返回一个包含动作类型和有效负载的对象,而你使用的是一个currying函数。通过useDispatch钩子访问的dispatch示例是你需要正确地将动作对象转发到商店的示例。

export const addTransaction = (amount) => ({
   type: "ADD_TRANSACTION",
   payload: amount,
})
ki0zmccv

ki0zmccv4#

因为您在useEffect的依赖项数组中提供了transactions。当您在useEffect依赖项数组中提供一些状态时,这意味着useEffect将仅在该状态改变时触发。如果您需要在每次组件呈现和transactions改变时调用countTotal,则可以使用两个useEffect
阅读此文章:https://reactjs.org/docs/hooks-reference.html#conditionally-firing-an-effect

hpcdzsge

hpcdzsge5#

如果你不想改变你的代码太多,并希望继续与此代码,然后有一个快速修复这个问题。你应该采取额外的状态在reducer和切换它,并开始听取它像下面
复位器代码:

const initialState = {
    transactions : [],
    refresh: false
  };
  
  export default function(state = initialState, action) {
    switch (action.type) {
      case "ADD_TRANSACTION":
        console.log('ADD_TRANS', action.payload)
        let trans = state.transactions;
        trans.push(action.payload)

        return {
          ...state,
          transactions: trans
          refresh: !state.refresh
        };
      default:
       return state;
    }
  }

主文件:

import logo from './logo.svg';
import './App.css';
import { useState, useEffect } from 'react'

import { addTransaction } from './actions/transActions';
import { countTotal } from './actions/countActions';

import { shallowEqual, useDispatch, useSelector } from 'react-redux';

function App() {
  const transactions = useSelector(state => {
   return state.trans.transactions
});
  const refresh = useSelector(state => state.trans.refresh);

  const count = useSelector(state => state.count.total);
  
  const dispatch = useDispatch()

  useEffect(() => {
    console.log("useEffect", transactions)
    dispatch(countTotal(transactions))
  }, [transactions, refresh])

  console.log('transactions', transactions)

  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
       <h1>{count}</h1>
       <br></br>
       <div>
       <button style={{width:90, height:60, fontSize: 40, backgroundColor: 'teal', border: '0px', color: 'white'}} onClick={() => {
        dispatch(addTransaction(10))
        }} type="button"> + 10</button> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
       <button style={{width:90, height:60, fontSize: 40, backgroundColor: 'indianred', border: '0px', color: 'white'}}  onClick={() => dispatch(addTransaction(-10))} type="button"> - 10 </button>

       </div>
       </header>

    </div>
  );
}

export default App;

相关问题