Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/433.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/reactjs/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Reactjs-使用复选框从数组中添加/删除项并存储_Javascript_Reactjs_Redux - Fatal编程技术网

Javascript Reactjs-使用复选框从数组中添加/删除项并存储

Javascript Reactjs-使用复选框从数组中添加/删除项并存储,javascript,reactjs,redux,Javascript,Reactjs,Redux,Prerquisite 我正在获取一个帐户列表(Ajax请求),并在页面加载时显示(旁边有一个复选框)。默认情况下,将选择所有帐户并将其添加到存储(redux) 目标 选中/取消选中复选框时,从阵列和存储(redux)中添加/删除帐户: saveAccount = (e, i, accountNumber, productName) => { const data = {}; data['id'] = i data['accountNumber'] = accountNumbe

Prerquisite

我正在获取一个帐户列表(Ajax请求),并在页面加载时显示(旁边有一个复选框)。默认情况下,将选择所有帐户并将其添加到存储(redux)

目标

选中/取消选中复选框时,从阵列和存储(redux)中添加/删除帐户:

saveAccount = (e, i, accountNumber, productName) => {
  const data = {};
  data['id'] = i
  data['accountNumber'] = accountNumber
  data['productName'] = productName

  if(this.props.checkboxStatus[i].checked === true){
    let accountArray = Array.from(this.props.account)
    accountArray[i].isSelected = true
    this.props.addAccount(accountArray)
  }
  else {
    let accountArray = Array.from(this.props.account)
    accountArray[i].isSelected = false
    this.props.addAccount(accountArray)
  }
}
  • 选中checbox-->将帐户添加到阵列和存储
  • 复选框未选中-->从阵列和存储中删除帐户(&S)
逻辑

我创建了两个单独的操作和还原:

  • 一个是管理复选框状态
  • 一个用于管理向阵列中添加/删除帐户& 贮藏
当测试我的代码时,它在开始时运行良好,但最终添加/删除的帐户不正确。问题一定在savingAccount()中,但不确定我做错了什么

我的代码

将数据预填充到ComponentWillMount()中的存储:

减速器

function Eligible(state = { products: {}, account: [], checkboxStatus: [] }, action){
  switch (action.type){
    case ADD_PRODUCTS:
      return {
        ...state,
        products: action.data
      }
    case ADD_ACCOUNT:
      return {
        ...state,
        account: action.data
      }
    case TOGGLE_CHECKBOX:
      return {
        ...state,
        checkboxStatus: action.data
      }
    default:
      return state
  }
}
行动

export const ADD_PRODUCTS = 'ADD_PRODUCTS'
export const ADD_ACCOUNT = 'ADD_ACCOUNT'
export const TOGGLE_CHECKBOX = 'TOGGLE_CHECKBOX'

export function addProducts(data){
  return {type: ADD_PRODUCTS, data}
}

export function addAccount(data) {
  return { type: ADD_ACCOUNT, data}
}

export function toggleCheckbox(data) {
  return { type: TOGGLE_CHECKBOX, data}
}
正在更新复选框状态:

  toggleChange = (checkbox) => {
    let toggleCheckbox = this.props.checkboxStatus
    toggleCheckbox[checkbox.id].checked = !checkbox.checked
    this.props.toggleCheckbox(toggleCheckbox)
  }

我认为,
this.setState
的异步性可能导致了一个问题

此状态
包含
帐户
复选框

this.state = {
  accounts: [],
  checkboxes: []
}
在更改事件处理程序中,调用两个函数:

onChange = {(e) => {
    this.toggleChange(this.props.checkboxStatus[i])
    this.saveAccount(e, i, item.accountNumber, item.accountName)
}}
第一次切换更改:

toggleChange = (checkbox) => {
    let toggleCheckbox = [...this.state.checkboxes];

    toggleCheckbox[checkbox.id].checked = !checkbox.checked
    this.setState({
        checkboxes: toggleCheckbox
    })

    this.props.toggleCheckbox(this.state.checkboxes)
}
您正在更新状态的checkbox属性(通过this.setState)——所有这些都很好。但是在最后一行,您正在将
this.state.checkbox
传递出去。由于this.setState是异步的,这可能不会反映您刚才所做的更改(您可以改为发送
toggleCheckbox

事件处理程序中调用的下一个函数是saveAccount,它包含(部分):

这里是this.state的当前值(由于异步设置状态,该值可能很旧)。更新它的.accounts属性,然后将整个内容(包括
.accounts
.checkbox
)发送到
this.setState

由于
.checkbox
状态可能已旧(以前的
this.setState
可能尚未启动),这将使旧的.checkbox状态排队,以覆盖您试图保存在
toggleChange()
中的新状态

可以使用
this.setState({accounts:addAccountState.accounts})
来快速解决这个问题,但也可能存在其他问题(比如直接修改
this.state
属性)

因为setState是异步的,所以在同一更新中后续调用 循环将覆盖以前的更新,并且以前的更改将 迷路了


关于存储和状态分离。。。一种选择可能是根本不单独存储复选框,而是根据选择的帐户计算它们

当然,这将取决于您的应用程序的需要,因此为了举例,我将做一些假设

  • 您的应用程序需要选定帐户的列表
  • 您的组件需要显示所有帐户的列表
  • 组件对每个帐户都有复选框:checked=selected=应用程序“selected accounts”列表的一部分
在这种情况下,我将通过
props
传递所选帐户的列表

在该组件中,我将拥有本地状态中所有帐户的列表(如果您的“所有帐户”列表已经通过道具传入,那么只需使用该列表即可-不需要本地状态)

在组件的render函数中,我将根据“selected accounts”列表中是否存在帐户来计算是否应选中复选框。如果它存在,就会被检查。如果没有,则不检查

然后,当用户单击复选框时,我将调度函数,从“所选帐户”列表中添加或删除帐户,仅此而已。帐户将被添加或删除,这将导致您的道具更新,这将重新呈现您的组件,这将根据需要选中或取消选中复选框


这可能不完全符合您特定应用程序的需要,但我希望它能给您一些想法!:)

你能展示一下你的行动以及你是如何分派的吗?另外,在
saveAccount
中,无论您添加的帐户处于选中状态,这是否正确
this.props.addAccount(removeCountState.accounts)
刚刚用我的操作更新了我的问题。在saveAccount中,我有一个条件,如果选中复选框,则仅添加,如果未选中复选框,则仅删除(this.props.checkboxStatus[I].checked==true)(…)else(){…}可能,您的操作和状态未同步。同时添加please toggleChange代码。谢谢,您正在尝试在本地州和redux中存储帐户状态。根据我的经验,当事情不同步时,这会导致问题。要么坚持100%redux,要么坚持100%本地状态。不要试图混用这两种方法。我知道,刚刚用toggleChange()更新了我的问题,因此this.setState的异步性可能是导致问题的原因。如何更新代码以仅使用存储?我假设存储中的数据通过其
道具传递到此组件,对吗?如果是这样,您只需从组件中删除本地状态,并将其基于
props
数据即可。修改将通过分派修改redux数据的函数来完成(然后更新
道具
,并导致组件重新渲染)。也就是说,如果数据只应用于一个组件,它不一定需要在redux中(本地状态可以)。但是,如果您有redux中的数据,请不要将相同的数据保存在本地州并尝试同步它们-只需使用redux即可。我已使用最新的代码更新了我的问题,正如建议的那样,我现在只使用store(redux)来避免不同步的问题,但我
onChange = {(e) => {
    this.toggleChange(this.props.checkboxStatus[i])
    this.saveAccount(e, i, item.accountNumber, item.accountName)
}}
toggleChange = (checkbox) => {
    let toggleCheckbox = [...this.state.checkboxes];

    toggleCheckbox[checkbox.id].checked = !checkbox.checked
    this.setState({
        checkboxes: toggleCheckbox
    })

    this.props.toggleCheckbox(this.state.checkboxes)
}
const addAccountState = this.state

if(this.props.checkboxStatus[i].checked === true){
    addAccountState.accounts = addAccountState.accounts.concat(data)
    this.setState(addAccountState)
    this.props.addAccount(addAccountState.accounts)
}