从我的redux状态删除项目会产生多个错误

时间:2019-03-29 15:27:46

标签: reactjs redux state jsx

我有2个问题:

  1. 最初,我可以通过动作创建者和我的reducer将客户端添加到空数组中。但是,每当我从列表中删除项目并尝试向其添加新客户端时,都会给我一个错误:TypeError:散布不可迭代实例的无效尝试。

  2. 当我说要删除项目时,真正发生的是创建客户端,然后单击其中一个旁边的删除按钮时,所有客户端都将删除。控制台中没有错误,但是我只想删除具有相应ID的特定客户端。

这是我的代码!

Clients.js

import React, { Component } from 'react'
import AddClient from './AddClient'
import {connect} from 'react-redux'
import {deleteClient} from '../../store/actions/clientActions'

class Clients extends Component {

  handleClick = (id) => {
    console.log(id)
    this.props.deleteClient(id)
  }

  render() {
    const {clientList} = this.props
    return (
      <div className="container mt-5">
        <h2>Here Are Your List of Clients...</h2>
        {clientList && clientList.map(client => {
          return(
            <div key={client.id}>
              <div>
                Client Name: {client.name} | Client Price: {client.price}
                <button onClick={() => {this.handleClick(client.id)}}>Delete</button>
              </div>      
            </div>
          )
        })}
        <AddClient/>
      </div>
    )
  }
}

const mapStateToProps = (state) => {
  return {
    clientList : state.clients.clientList,
  }
}

const mapDispatchToProps = (dispatch) => {
  return{
    deleteClient : (id) => dispatch(deleteClient(id)) 
  }
}

export default connect(mapStateToProps, mapDispatchToProps)(Clients)

操作:

export const addClient = (client) => {
    return(dispatch, getState) => {
        dispatch({type: 'ADD CLIENT', client})
    }
}

export const deleteClient = (id) => {
    return(dispatch, getState) => {
        dispatch({type: 'DELETE CLIENT', id})
    }
}

减速器:

const initState = {
    clientList: []
}

const clientReducer = (state = initState, action) => {
    switch (action.type) {
        case 'ADD CLIENT' : 
            action.client.id = Math.random();
            let clientList =  [...state.clientList, action.client];
            clientList.sort((a, b) => a.name.localeCompare(b.name));
            return {
                clientList
            };

        case 'DELETE CLIENT' :
            const id = action.id;
            clientList = state.clientList.filter(client => 
                {return client.id !== id});
            return clientList;

        default : return state;
    }
}

export default clientReducer

最后,这是AddClient.js

import React, { Component } from 'react'
import {connect} from 'react-redux'
import {addClient} from '../../store/actions/clientActions'

class AddClient extends Component {
  state = {
    id: null,
    name: null,
    price: null,
  }

  handleChange = (e) => {
      this.setState({
          [e.target.id] : e.target.value
      })
  } 

  handleSubmit = (e) => {
    e.preventDefault();
    this.props.addClient(this.state);
    e.target.reset();
  }

  render() {
    return (
      <div>
        <form onSubmit={this.handleSubmit} className="mt-5">
            <h3>Add a new client:</h3>
            <label htmlFor="name">Client Name: </label>
            <input type="text" id="name" onChange={this.handleChange}/><br/>
            <label htmlFor="price">Client Price: </label>
            <input type="text" id="price" onChange={this.handleChange}/> <br/>
            <button className="btn btn-primary">Add Client</button>
        </form>
      </div>
    )
  }
}

const mapDispatchToProps = (dispatch) => {
  return {
    addClient: (client) => dispatch(addClient(client))
  }
}

export default connect(null, mapDispatchToProps)(AddClient)

感谢您的所有帮助,对于React和Redux来说,我还是一个新手。让我知道您是否还想查看其他代码。

3 个答案:

答案 0 :(得分:0)

这是完成删除的方法:

export const deleteClient = (id) => {
    const index = find the index of the client you want to delete from the array
    return(dispatch, getState) => {
        dispatch({type: 'DELETE CLIENT', index})
    }
}



case 'DELETE CLIENT' :
    return {
        ...state,
        clientList: [
              ...state.clientList.slice(0, action.index),
              ...state.clientList.slice(action.index + 1)
        ]
    }

答案 1 :(得分:0)

我知道了,问题出在我的clientReducer.js

这需要更改:

case 'DELETE CLIENT' :
    const id = action.id;
    clientList = state.clientList.filter(client => 
       {return client.id !== id});
    return clientList;

到...

case 'DELETE CLIENT' :
    const id = action.id;
    let newClientList = state.clientList.filter(client => {
        return id !== client.id;
    })
    return {clientList : newClientList};

答案 2 :(得分:0)

case 'DELETE CLIENT' :
        const id = action.id;
        const clientList = state.clientList.filter(client => 
            {return client.id !== id});
        return {
            ...state,
            clientList
        }

您当前仅返回一个数组,而不是一个对象。由于这可能是您当前在redux存储中拥有的唯一东西,它没有中断(在ADD操作中),但是您可能想先应用先前的状态,然后将新过滤的客户列表添加到返回的状态。