如何从Redux存储中的数组中删除特定元素

时间:2019-05-25 16:23:50

标签: javascript reactjs redux

我是新来的Redux并做出反应。仍在做简单的教程。我设法创建了2个简单的组件;一个组件在屏幕上输出(作为列表)redux存储中的数组中的任何内容,另一个组件包含一个按钮和一个文本字段,基本上将其添加到存储中的该数组中。

我想添加一项功能,使我可以根据用户单击的内容删除列表中的特定条目。我正在考虑在每个循环遍历数组的set FLASK_APP = app.py 标签旁边创建一个<button>,这些按钮将对应于相应的列表元素。但是我不确定该怎么做。

我尝试在创建每个<li>标签时创建一个按钮,但是在控制台上出现错误,指出列表中的每个元素都需要一个唯一的ID。然后,我决定在我的商店中创建另一个名为<li>的数组,该数组将包含唯一的ID以及列表的ID,但是它失去了控制力。我想我可能会为此复杂化。这是我目前所拥有的:

组件: List.jsx(负责输出列表)

buttons

SubmitButton.jsx(负责输出按钮和文本字段)

import React from 'react'
import { connect } from "react-redux";

const ListComp = ({ lists }) => (
    <div>    
        <ul>
            {console.log(lists)}
            {lists.map( element => (
                    <li key={element.id}>
                        {element.titleToBeAddedToList}
                    </li>
            ))}
        </ul>
    </div>
)

const mapStateToProps = state => {
    return {
        lists: state.lists
    };
}
const List = connect(mapStateToProps)(ListComp)

export default List;

减速器:

import React from 'react'
import { connect } from "react-redux";
import uuidv1 from "uuid";
import { addList } from "../actions/index";
import { addButton } from "../actions/index"

function mapDispatchToProps(dispatch){
    return {
        addlist: article => dispatch(addList(article)),
        addbutton: idOfButton => dispatch(addButton(idOfButton))
      };
}

class Submit extends React.Component{

    constructor(){
        super();
        this.handleChange = this.handleChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);        
    }

    handleChange(event) {
        this.setState({ [event.target.id]: event.target.value });
    }

    handleSubmit(event) {
        event.preventDefault();
        const {titleToBeAddedToList} = this.state;
        const id = uuidv1();
        const button_id = uuidv1();
        //Dispatching the action:
        this.props.addlist({ titleToBeAddedToList, id });
        this.props.addbutton({id, button_id});        
        //Once we've dispatched an action, we want to clear the state:
        this.setState({ titleToBeAddedToList: "" });
    }

    render() {
        return (
          <form onSubmit={this.handleSubmit}>
            <div className="form-group">
              <label htmlFor="title">Title</label>
              <input
                type="text"
                className="form-control"
                id="titleToBeAddedToList"
                onChange={this.handleChange}
              />
            </div>
            <button type="submit" className="btn btn-success btn-lg">
              SAVE
            </button>
          </form>
        );
      }
}

const SubmitButton = connect(null, mapDispatchToProps)(Submit)

export default SubmitButton;

操作:

const initialState = {
lists: [],
buttons: []
};

function rootReducer (state = initialState, action) {
    if(action.type === "ADD_LIST" ){
        return Object.assign({}, state, {
            lists: state.lists.concat(action.payload)
          });
    } else if(action.type === "ADD_BUTTON"){
        return Object.assign({}, state, {
            buttons: state.lists.concat(action.payload)
          });
    } else if(action.type === "DELETE_FROM_LIST"){
        //.....//
    }
    return state;
}

export default rootReducer;

商店:

    export function addList(payload) {
    return { type: "ADD_LIST", payload }
};

export function addButton(payload){
  return {type: "ADD_BUTTON", payload }
}

export function deleteList(payload){
  return { type: "DELETE_FROM_LIST", payload }
}

3 个答案:

答案 0 :(得分:0)

else if (action.type === "DELETE_FROM_LIST") {
  return Object.assign({}, state, {
    buttons: state.lists.filter(item => (item.id !==action.payload))
  });
}

您可以使用filter()进行删除。

答案 1 :(得分:0)

您可以将Math.random()用作唯一的键标识符,如果单击该按钮,它将使用ID调用操作deleteItem,该操作绑定到reducer传递ID,然后可以使用用于标识元素并将其从列表中删除的ID。

import React from 'react'
import { connect } from "react-redux";
import { deleteItem } from './actions';

const ListComp = ({ lists }) => (
   <div>    
       <ul>
          {console.log(lists)}
          {lists.map( element => (
             <li key={Math.random()} key={element.id}>
                 {element.titleToBeAddedToList}
                  <button onClick={() => deleteItem(element.id)}>X</button>
              </li>
                ))}
       </ul>
    </div>
)

const mapStateToProps = state => {
   return {
      lists: state.lists
    };
}
const List = connect(mapStateToProps, {deleteItem})(ListComp) // Make it available to component as props

export default List;



Action:

export function deleteElement(id) {
  return function(dispatch) {
    return dispatch({type: "DELETE_FROM_LIST", payload: id})
  }
}



Reducer:

 case 'DELETE_FROM_LIST': {
  const id = action.payload;
  return {
    ...state,
    list: state.list.filter(item => item.id !== id)
  }
}

答案 2 :(得分:0)

这是一个最小的react-redux工作示例,其中包含从redux存储中的数组中删除项目的所有片段。

// reducer.js
const reducer = (state, action) => {
  switch (action.type) {
    case 'DELETE': 
    return state.filter(item => (
      item.id !== action.payload.id
    ))
    default: return state;
  }
}

// Item.js

const Item = ({id, onClick, label}) => (
  <li>
    {label} 
    <button onClick={ () => onClick(id) }>
      delete
    </button>
  </li>
)


// ListContainer.js

const mapStateToProps = state => ({ items: state })

const ListContainer = ReactRedux.connect(mapStateToProps)(class extends React.Component {

  handleDelete = id => {
    const { dispatch } = this.props;
    dispatch({ type: 'DELETE', payload: { id } })  
  }


  render() {
    const { items } = this.props;
  
    return items.map(({id, label}) => (
      <Item
        label={label}
        id={id}
        onClick={this.handleDelete}
      />
    ))
  }
})

// Main.js

const initialState = [
  { id: 1, label: 'item 1' },
  { id: 2, label: 'item 2' },
  { id: 3, label: 'item 3' },
  { id: 4, label: 'item 4' }
]

const store = Redux.createStore(reducer, initialState);

class App extends React.Component {
  render(){
    return (
    <ReactRedux.Provider store={store}>
      <ListContainer />
    </ReactRedux.Provider>
    );
  }
}

ReactDOM.render(<App />, document.getElementById('root'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.1/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/6.0.1/react-redux.js"></script>
<div id="root"></div>