首页 > 解决方案 > 通过操作从数组中删除一个项目

问题描述

我想让删除项目减速器添加项目减速器是:

export const addItems= (state= [], action)=> {
    switch (action.type) {
        case 'ADD_ITEM':
            return [
                ...state,
                action.product
            ]
        default:
            return state;
    };
};

add itme 的动作创建者是:

export const showItems = (author,price) =>{
    return((dispatch)=>{
        dispatch({
            type:'ADD_ITEM',
            product:{
                author,
                price
            }
        });
    });
};

删除动作创建者是:

export const removeItem = (index) =>{
    return((dispatch)=>{
        dispatch({
            type:'REMOVE_ITEM',
            payload: index
        });
    });
};

显示列表项的地图功能:

{showItems.map((item, index)=>{
                        return(
                            <ul key={index} className='d-flex justify-content-around'>
                                <button 
                                    type='button' 
                                    className='btn-close btn-danger' 
                                />
                                <p>{item.author}</p>
                                <p>{item.price}</p>
                            </ul>
                        );
                    })}

我的问题是:什么是remove item reducer?

标签: javascriptreactjsreact-reduxredux-reducersredux-actions

解决方案


如果您从列表中删除项目,则不应使用 index 作为 key,如果数据未存储在服务器上并由多个客户端访问,则可以让 reducer 为您创建唯一索引。

要从数组中删除一个项目,您可以使用Array.prototype.filter

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

const initialState = {
  items: [{ id: 1 }, { id: 2 }],
};
//action types
const ADD = 'ADD';
const REMOVE = 'REMOVE';
//action creators
// no need for remove to be a thunk
const remove = (id) => ({
  type: 'REMOVE',
  payload: id,
});
const add = () => ({ type: ADD });
//function to generate unique id based on state
const getId = (state) =>
  Math.max(
    ...(state.items.length
      ? state.items.map(({ id }) => id)
      : [1])
  ) + 1;
const reducer = (state, { type, payload }) => {
  if (type === ADD) {
    return {
      ...state,
      items: state.items.concat({
        id: getId(state),
      }),
    };
  }
  if (type === REMOVE) {
    //use Array.prototype.filter to remove item from array
    return {
      ...state,
      items: state.items.filter(({ id }) => id !== payload),
    };
  }
  return state;
};
//selectors
const selectItems = (state) => state.items;
const createSelectItemById = (itemId) =>
  createSelector([selectItems], (items) =>
    items.find(({ id }) => id === itemId)
  );
//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 Item = React.memo(function Item({ id }) {
  const selectItem = React.useMemo(
    () => createSelectItemById(id),
    [id]
  );
  const item = useSelector(selectItem);
  const dispatch = useDispatch();
  return (
    <li>
      <pre>{JSON.stringify(item)}</pre>
      <button onClick={() => dispatch(remove(id))}>
        remove
      </button>
    </li>
  );
});
const App = () => {
  const items = useSelector(selectItems);
  const dispatch = useDispatch();
  return (
    <div>
      <button onClick={() => dispatch(add())}>
        Add Item
      </button>
      <ul>
        {items.map(({ id }) => (
          // use unique id for key when you re order
          //   or remove items
          <Item key={id} id={id} />
        ))}
      </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>
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>

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

有关更多不可变更新模式,请参阅这篇文章


推荐阅读