如何通过名称而非索引删除Redux Form中FieldArray的多个指定元素
Redux Form FieldArray 批量删除与表单更新问题解决方案
问题1:FieldArray 批量删除索引错位
原因
你推测的问题点正确,fields.remove()每次执行后数组长度会动态变短,正序删除时预先拿到的索引会和实时数组索引不匹配,最终导致删错、漏删甚至索引越界。
解决方案
把待删除的索引先按照降序排序,从数组末尾往前删除,后面元素的删除操作不会影响前面元素的原有索引,就不会出现匹配错误的问题。
代码修改示例:
<MultiSelect placeholder="Delete project group" onChange={(v) => { const diff = difference(addedGroups, v) if (!isEmpty(diff)) { const groupToDelete = diff[0] // 先收集所有待删除的索引 const indexesToRemove = projectsByGroup[groupToDelete].map(p => addedProjects.indexOf(p)) // 索引降序排序后依次删除 indexesToRemove.sort((a, b) => b - a).forEach(idx => removeElement(idx)) deleteGroup(groupToDelete) }} options={projectGroupNames} value={addedGroups} inline />
问题2:change方法修改表单值不生效
原因
redux-form导出的change是action creator,调用后只会生成标准的Redux action对象,你没有把这个action传给dispatch执行,自然不会触发Redux状态更新,表单也就不会响应变化。
解决方案
给change调用套上dispatch即可,修改对应代码行:
import { change } from 'redux-form' export const deleteVariantSearchProjectGroup = (projectGroupGuid) => { return (dispatch, getState) => { const state = getState() const projectsInGroup = state.projectsByProjectGroup[projectGroupGuid] const allProjectFields = getProjectsFamiliesFieldInput(state) const remainingProjectFields = allProjectFields.filter(projectField => !projectsInGroup.includes(projectField.projectGuid)) // 给change方法包上dispatch触发状态更新 dispatch(change(SEARCH_FORM_NAME, 'projectFamilies', remainingProjectFields)) dispatch({ type: UPDATE_VARIANT_SEARCH_ADDED_GROUPS, newValue: without(getState().variantSearchAddedProjectGroups, projectGroupGuid) }) } }
内容的提问来源于stack exchange,提问作者Nikita Vlasenko
相关产品推荐
相关产品推荐

