微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在 react redux 中设置状态时,我可以获取当前对象的索引吗?

如何解决在 react redux 中设置状态时,我可以获取当前对象的索引吗?

我正在使用 react redux 开发一个待办事项应用程序,它的初始状态是一个对象 initialState 并且有一个数组 task,它是一个空数组。设置 task 的值时,我似乎找不到获取对象的当前索引以将其分配给 id方法。 我曾尝试使用 indexOf()findindex(),但还没有找到处理它的最佳方法。 我希望 id 等于其对象的索引。 (如果对象在任务数组中的索引为 0,则该 id 等于 0) 并且在数组更改或具有多个对象时也可以工作。感谢您的帮助,谢谢

这是我的初始状态

export const initialState = {
    task: []
}

这是我的减速机

const managetodoReducer = (state,action) => {
    switch(action.type) {
        case "ADD_Todo":
            return (
                {
                    ...state,task: [
                        ...state.task,{
                            name: "This is the name",id: state.task.findindex(x => x.name === state.task.name),complete: false
                    }]
                }
            )

            default:
                return state
            }
        }

解决方法

您可以使用 state.tasks.length,但是当您有 2 个任务时会中断,删除第一个然后添加一个任务(参见示例,您将以 id 为 1 的 2 个任务结束)。

const { Provider,useDispatch,useSelector } = ReactRedux;
const { createStore,applyMiddleware,compose } = Redux;

const initialState = {
  tasks: [{ id: 0 },{ id: 1 }],};
//action types
const ADD_TASK = 'ADD_TASK';
const REMOVE_TASK = 'REMOVE_TASK';
//action creators
const addTask = () => ({
  type: ADD_TASK,});
const removeTask = (id) => ({
  type: REMOVE_TASK,payload: id,});
const reducer = (state,{ type,payload }) => {
  if (type === ADD_TASK) {
    return {
      ...state,tasks: state.tasks.concat({ id: state.tasks.length }),};
  }
  if (type === REMOVE_TASK) {
    return {
      ...state,tasks: state.tasks.filter(({ id }) => id !== payload),};
  }
  return state;
};
//selectors
const selectTasks = (state) => state.tasks;
//creating store with redux dev tools
const composeEnhancers =
  window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(
  reducer,initialState,composeEnhancers(
    applyMiddleware(
      () => (next) => (action) => next(action)
    )
  )
);
const App = () => {
  const tasks = useSelector(selectTasks);
  const dispatch = useDispatch();
  const remove = (id) => dispatch(removeTask(id));
  const add = () => dispatch(addTask());
  return (
    <div>
      <button onClick={add}>Add task</button>
      <ul>
        {tasks.map((task) => (
          <li key={task.id}>
            <pre>{JSON.stringify(task)}</pre>
            <button onClick={() => remove(task.id)}>
              remove
            </button>
          </li>
        ))}
      </ul>
    </div>
  );
};

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>

<div id="root"></div>

不建议使用索引,除非您绝对have to并且在您重新订购或从列表中删除项目时永远不要这样做。

我建议制作一个生成 id 的函数:

//in case you use redux persist and tasks will persist between reloads
const genId = (state) =>
  Math.max(...state.map(({ id }) => id).concat(-1)) + 1;    

//reducer
id: genId(state.tasks),

见下面的工作示例

const { Provider,});
//in case you use redux persist and tasks will persist between reloads
const genId = (state) =>
  Math.max(...state.map(({ id }) => id).concat(-1)) + 1;
const reducer = (state,tasks: state.tasks.concat({
        id: genId(state.tasks),}),document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>

<div id="root"></div>

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。