【问题标题】:Component update but state does not update redux toolkit组件更新但状态不更新 redux 工具包
【发布时间】:2021-11-09 05:56:35
【问题描述】:

我有一个待办事项列表应用程序,我将待办事项列表存储在一个名为 list 的状态中,它是一个数组。当我添加一个列表时,组件会重新渲染并更新 UI,但是当我在调用 reducer 后控制台记录列表时,列表不会更新。这是控制台。列表前的对象是警告信息

这是我的回购链接:https://github.com/yustinayasin/tugas-react/tree/day16/day16

这是我在组件中添加列表的代码:

function App() {
  const [kegiatan, setKegiatan] = useState('');
  const [isEditing, setIsEditing] = useState(false);
  const [editID, setEditID] = useState(null);
  const list = useSelector((state) => state.list);
  const alert = useSelector((state) => state.alert);
  const dispatch = useDispatch();
 
  const handleSubmit = (e) => {
    e.preventDefault();
    if(!kegiatan) {
      dispatch(setAlert({show: true, msg: 'Masukkan kegiatan terlebih dahulu', type: 'danger'}))
    } else if (kegiatan && isEditing) {
      dispatch(editToList({title: kegiatan, id: editID}));
      setKegiatan('');
      setEditID(null);
      setIsEditing(false);
      dispatch(setAlert({show: true, msg: 'Kegiatan berhasil diubah', type: 'success'}));
    } else {
      console.log('masuk');
      dispatch(addToList({title: kegiatan}));
      dispatch(setAlert({show: true, msg: 'Kegiatan ditambahkan ke dalam list', type: 'success'}));
      console.log(list);
      setKegiatan('');
    }
  }

  const clearList = () => {
    dispatch(setAlert({show: true, msg: 'List kegiatan kosong', type: 'danger'}));
    dispatch(clearAllList());

  }

  const removeItem = (id) => {
    dispatch(setAlert({show: true, msg: 'Kegiatan berhasil dihapus', type: 'danger'}));
    dispatch(deleteListItem(), {id: id});
  }

  const editItem = (id) => {
    const specificItem = list.find((item) => item.id === id);
    setIsEditing(true);
    setEditID(id);
    setKegiatan(specificItem.title);
  }

  const completeItem = (id) => {
    dispatch(completeItemList({id: id}));
  }

  return (
    <section className="section-center">
      <Navbar/>
      <form className="kegiatan-form" onSubmit={handleSubmit}>
        {alert.show && <Alert />}
        <h3>Daftar Kegiatan</h3>
        <div className="form-control">
          <input 
            type="text" 
            className="kegiatan" 
            placeholder='contoh: beli beras' 
            value={kegiatan} 
            onChange={(e) => setKegiatan(e.target.value)}
            />
          <button className="submit-btn" type="submit">
            {isEditing ? 'edit' : 'submit'}
          </button>
        </div>
      </form>
      {list.length > 0 && 
        <div className="kegiatan-container">
          <List completeItem={completeItem} removeItem={removeItem} editItem={editItem}/>
          <button className="clear-btn" onClick={clearList}>
            hapus semua kegiatan
          </button>
        </div>
      }
    </section>
  );
}

export default App

这是我的减速器代码

import { createSlice } from '@reduxjs/toolkit'

const initialState = {
  list: []
}

export const listSlice = createSlice({
  name: 'list',
  initialState,
  reducers: {
    addToList: (state, action) => {
        console.log(action.payload.title);
        return [...state.list, {id: new Date().getTime().toString(), title: action.payload.title, complete: false}];
    },
    editToList: (state, action) => {
        return [...state.list, state.list.map((item) => {
            if(item.id === action.payload['id']) {
                return {...item, title: action.payload['kegiatan']};
            }
            return item;
        })]
    },
    deleteListItem: (state, action) => {
        return state.list.filter((item) => item.id !== action.payload.id);
    },
    clearAllList: () => {
        return initialState;
    },
    completeItemList: (state, action) => {
        return [...state.list, state['list'].map((item) => {
            if(item.id === action.payload['id']) {
                return {...item, complete: !state.list.complete};
            }
            return item;
        })]
    }
  },
})


export const { completeItemList, editToList, addToList, deleteListItem, clearAllList} = listSlice.actions

export default listSlice.reducer

【问题讨论】:

  • 您似乎在调度添加列表操作后立即记录list。这就是为什么您会看到以前的列表状态(即它似乎正在记录旧版本的列表)。另一种方法是使用带有列表的useEffect 作为依赖项,并在它更改时记录它。但是,我建议您使用浏览器的 Redux Devtools 扩展作为更集成的调试解决方案。
  • @Moistbobo 它有效。列表每次更新。但是当我想在 reducer 的 completeList 操作中使用状态时,我得到了一个未定义的值。你知道是什么问题吗?

标签: reactjs react-redux reducers toolkit


【解决方案1】:

尝试在仅传播状态内的列表项之前传播整个状态。而不是:

return [...state.list, {id: new Date().getTime().toString(), title: action.payload.title, complete: false}];,

做:

return{...state, [...state.list, {id: new Date().getTime().toString(), title: action.payload.title, complete: false}];}

【讨论】:

  • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-16
  • 2023-01-16
  • 1970-01-01
  • 2019-06-13
  • 2018-09-25
  • 2019-08-31
相关资源
最近更新 更多