Javascript Reactjs-使用复选框从数组中添加/删除项并存储
Prerquisite 我正在获取一个帐户列表(Ajax请求),并在页面加载时显示(旁边有一个复选框)。默认情况下,将选择所有帐户并将其添加到存储(redux) 目标 选中/取消选中复选框时,从阵列和存储(redux)中添加/删除帐户: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
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)
- 一个是管理复选框状态
- 一个用于管理向阵列中添加/删除帐户& 贮藏
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)
}