javascript - 在 redux 存储中切片数组总是会导致删除组件渲染上的最后一个数组项

标签 javascript reactjs redux react-redux

我有一个标尺组件,当我单击它时,它会通过向我的 redux 存储 添加 1 个标尺线来为我创建水平标尺线。到目前为止,我添加它们时没有任何问题,但我还想在双击它们时删除这些规则,我通过 action 将项目索引发送到我的 reducer,我在其中运行 array.slice 来删除我双击的规则。但无论如何,它只是为我弹出了最后一条规则。

我知道这在我渲染组件时会以某种方式发生,因为当我 console.log reducer 中的数组时,正确的元素会从中删除,但它的渲染方式有所不同。以下是我使用过的代码:

我的标尺组件:

class Rulers extends Component {
    render() {
        const { mousePosition, wheelY, dragY, rulerHGuides } = this.props;

        const ruleH = rulerHGuides.map((ruleH, i)=><RuleH index={i} wheelY={wheelY} dragY={dragY} key={i} {...ruleH} /> )

        return (
            <div>
                <div className="rules">
                    { ruleH }
                </div>
                <div className="ruler-horizontal" onClick={e=>{ store.dispatch( actions.rulerHGuides({top: mousePosition.y}) ) }}>
                    <span className="mouse-follow-h" style={{transform: `translateX(${mousePosition.x}px)`}}></span>
                    <svg id="svgH" xmlns="http://www.w3.org/2000/svg"></svg>
                </div>
            </div>
        )
    }
}

export default connect(state=>{
    const { mousePosition, rulerHGuides } = state;
    return { mousePosition, rulerHGuides }
})(Rulers)

RuleH 组件

class RuleH extends Component {
    constructor(props) {
        super(props)

        this.state = {
            rulezHDrag: 0,
            top: 0
        }
    }
    render() {
        const { wheelY, dragY, index, id } = this.props;
        const { rulezHDrag, top } = this.state;

        return (
            <DraggableCore onDrag={this.handleRuleH.bind(this)} enableUserSelectHack={false}>
                <span id={id} className="ruleH" style={{top, transform: `translate3d(0, ${(-wheelY) + dragY + rulezHDrag}px, 0)`}}
                    onDoubleClick={e=>{
                        store.dispatch( actions.removeRulerHGuide( index ) )
                        console.log(index);
                    }}
                ></span>
            </DraggableCore>
        )
    }
    componentDidMount() {
        this.setState({
            top: `${this.props.top - ((-this.props.wheelY) + this.props.dragY)}px`
        })
    }
    handleRuleH(e: MouseEvent, data: Object){
        const { rulezHDrag } = this.state;
        this.setState({
            rulezHDrag: rulezHDrag + data.deltaY
        })
    }
}

我的 Action 创建者:

// Ruler guides
// ==========================================
export const rulerHGuides = (hGuides) => {
    return {
        type: 'RULER_H_GUIDES',
        hGuides
    }
}
export const removeRulerHGuide = (index) => {
    return {
        type: 'REMOVE_RULER_H_GUIDE',
        index
    }
}

我的 reducer :

export const rulerHGuides = (state = [], action) => {
    switch (action.type) {
        case 'RULER_H_GUIDES':
            return [
                ...state,
                action.hGuides
            ]
        case 'REMOVE_RULER_H_GUIDE':
            return [
                ...state.slice(0,action.index),
                ...state.slice(action.index + 1)
            ]
        default:
            return state;
    }
}

我尝试使用array.filters而不是array.slice,但这不是问题,问题,无论是什么,都发生在我的组件内部,其中我正在映射我的 rulerHGuides 数组。

最佳答案

请使用某种形式的唯一id,而不是使用索引,并在创建时将其分配给规则。当您使用索引作为 React 组件的键时,删除项目后会使用相同的索引作为键,这会破坏重新渲染优化。

例如,索引为 0, 1, 2, 3 并删除 2 处的项目,您将剩下 0, 1, 2 > - 在那里您可以看到最后一个键被删除,这导致了您所描述的问题。

关于javascript - 在 redux 存储中切片数组总是会导致删除组件渲染上的最后一个数组项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41467002/

相关文章:

javascript - 图像可以显示在 JavaScript Alertbox 中吗

node.js - 开始使用 material-ui

javascript - React Hooks useEffect,添加依赖触发死循环

javascript - PropType 没有发出警告

Javascript 时间死区

javascript - 使用 HighCharts 动态更新同一图表上的两个系列

reactjs - redux-form FieldArray 修改 props

javascript - 模拟 store.getState()

javascript - 抽象 AJAX 调用,以便我可以使我的代码更加动态

使用唯一 ID 进行 Javascript 测试