简体   繁体   English

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

[英]How to delete a specific element from an array in the redux store

I am new to to redux and react. 我是新手,以减少和反应。 Still doing simple tutorials. 还在做简单的教程。 I managed to create 2 simple components; 我设法创建了2个简单的组件; one that outputs on the screen (as a list) whatever is in the array in the redux store, and the other component contains a button and a textfield which basically adds to that array in the store. 一个在屏幕上输出(作为列表)在redux存储中的数组中的任何内容,另一个组件包含一个按钮和一个文本字段,它基本上添加到存储中的该数组。

I would like to add a feature that will enable me to delete a specific entry in the list depending on what the user clicked on. 我想添加一项功能,使我能够根据用户点击的内容删除列表中的特定条目。 I am thinking of creating a <button> next to each <li> tag that gets rendered as it loops through the array, and these buttons will correspond to the respective list elements. 我想在每个<li>标签旁边创建一个<button> ,它在循环遍历数组时被渲染,这些按钮将对应于各自的列表元素。 But I'm not sure how to do that. 但我不知道该怎么做。

I've tried creating a button when each <li> tag gets created but I was getting an error on the console stating that each element in a list needs a unique ID. 我已经尝试在创建每个<li>标签时创建一个按钮但是我在控制台上收到错误,指出列表中的每个元素都需要一个唯一的ID。 I then decided to create another array in my store called buttons which will contain a unique id as well as the id of the list but it got out of hand. 然后我决定在我的商店中创建另一个名为buttons数组,它将包含一个唯一的id以及列表的id,但它已经失控。 I think I might be overcomplicating this. 我想我可能会过于复杂。 This is what I have at the moment: 这就是我现在所拥有的:

Components: List.jsx (responsible for outputting the list) 组件:List.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;

SubmitButton.jsx (responsible for outputting the button and textfield) SubmitButton.jsx(负责输出按钮和文本字段)

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;

Reducers: 减速器:

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;

Action: 行动:

    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 }
}

Store: 商店:

import { createStore } from "redux";
import rootReducer from "../reducers/index";

const store = createStore(rootReducer);

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

you can use filter() for delete. 你可以使用filter()进行删除。

You can use Math.random() as an unique key identifier, if the button is click it will call action deleteItem with the ID, action is bound to reducer pass on the ID, you can then use the ID to indentify elements and remove it in the list. 您可以使用Math.random()作为唯一键标识符,如果单击该按钮将调用具有ID的动作deleteItem ,动作绑定到减速器传递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)
  }
}

This is a minimal working react-redux example containing all the pieces to delete an item from an array in redux store. 这是一个最小的工作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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM