【问题标题】:Warning: flattenChildren(...): Encountered two children with the same key / Child keys must be unique警告:flattenChildren(...):遇到两个具有相同键的孩子/孩子键必须是唯一的
【发布时间】:2018-01-01 00:17:18
【问题描述】:

昨天我将react-router-dom 添加到我的项目中,现在当我离开并回到导航中的Sky 元素时,它重新加载了天空,我得到了

警告:flattenChildren(...):遇到两个孩子使用相同的密钥,element-id-50。子键必须是唯一的;当两个孩子共享一个密钥时,只会使用第一个孩子。

(上面使用的数字 50 只是一个示例,每次使用不同的 id 都会抛出此错误约 40 次)

问题似乎出在我的sky.js 文件中:

componentWillMount() {
    this.props.dispatch(requestSkySetup());
    this.props.dispatch(requestAllElements());

    this.setState({loadedSky: true, loadedElements: true});
}

因为每次我要去另一个屏幕,这个组件都会卸载,然后当我回来时重新安装。

receiveSkySetup 完成时,sky.js 中的render 函数会创建一组名为Sectors 的div,每个Sector 会创建几个名为Slots 的div。

那么在Slot.render里面我有:

return connectDropTarget(
            <div className={showOutline ? 'slot showOutline' : 'slot'} style={style} onClick={interactable ? this.handleClick : null}>
                {
                    elements
                        .map(e => (
                            <SkyElement
                                id={e.id}
                                key={`element-id-${e.id}`}
                                title={e.title}
                                size={150}
                                opacity={e.opacity}
                                glow={e.glow}
                                color={e.color}
                                sectorId={e.sectorId}
                                slotId={e.id}
                                dispatch={this.props.dispatch}
                                isDragging={false}
                                transformElement={false} />
                        ))
                }
            </div>
        );

上述SkyElement 调用中的key 元素是每次安装时引发40 多个错误的原因。

如果需要,很乐意提供更多代码。

任何帮助都会非常有帮助。谢谢!

编辑:控制台日志记录元素

再深入一点,我店里的商品翻了一番。

因此,在 sky 标签的第二次渲染中,元素 ID 的完整列表是 ["0", "1", "2", "3", "4", "5", "6", "7", "17", "18", "19", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "77", "78", "0", "1", "2", "3", "4", "5", "6", "7", "17", "18", "19", "55", "56", "57", "58", "59", "60", "61", "62", "63", "64", "65", "66", "67", "77", "78"]

在第 3 次渲染时,元素 0-78(适用于上述数组的 id)将再次添加到数组中

Slot.js

const mapStateToProps = ({elements}, ownProps) => {
    return {
        elements: getElementsBySlotId(elements, ownProps.id),
    };
};

elements 这里将是 n 乘以 Sky 完成的加载次数。

sky.js

const mapStateToProps = ({sky, elements}) => {
    return {
        sectors: getSky(sky).sectors,
        elements: getElementsByKeyName(elements, 'visibleElements'),
        unplacedElements: getElementsByKeyName(elements, 'unplacedElements'),
    };
};

打印elements.length 我看到他们在这里也翻了一番。 Slot.js 是从同一家商店拉出来的,所以这是有道理的

在我的elements/reducer.js

case 'receiveAllElements':
        const visibleElements = {};
        const unplacedElements = {};

        const elements = action.elements.reduce((result, index) => {
            result[`${index.id}`] = index;
            return result;
        }, {});

        const keys = Object.keys(elements);
        for (const key of keys) {
            const e = elements[key];

            if (e.sectorId === null) {
                unplacedElements[key] = e;
            } else {
                visibleElements[key] = e;
            }
        }

        const visibleIds = Object.keys(visibleElements);
        const unplacedIds = Object.keys(unplacedElements);
        console.log(visibleIds);
        console.log(unplacedIds); // logging these, the numbers are consistent and don't double, triple etc with each load

        return {
            ...state,
            elementsMap: {
                ...state.elementsMap,
                ...elements,
            },
            visibleElements: [...state.visibleElements, ...visibleIds],
            unplacedElements: [...state.unplacedElements, ...unplacedIds],
        };

也许里面有什么东西导致计数加倍?

【问题讨论】:

  • 你试过.map((e, index) =&gt; (key={index}吗?
  • 我没有,但我不确定它会有所作为。例如,当我卸载并重新安装 Sky 元素时,对于 element-id-50 再次引发错误,如果我重复它,错误将再次发生 50。我想 index 也会发生同样的情况
  • 每个槽的渲染是否相同elements
  • 每个插槽呈现一个 uniq 元素或一组元素。没有重叠
  • 你能更新一下元素数组是如何填充的吗?

标签: javascript reactjs redux react-redux electron


【解决方案1】:

这里的问题是

    return {
        ...state,
        elementsMap: {
            ...state.elementsMap,
            ...elements,
        },
        visibleElements: [...state.visibleElements, ...visibleIds],
        unplacedElements: [...state.unplacedElements, ...unplacedIds],
    };

visibleElements(和unplacedElements 值)。

[...state.visibleElements, ...visibleIds] 将连接 2 个数组,因此由于每次我返回 Sky 选项卡时都会命中此代码,因此它将 ...visibleIds 中的新 ID 添加到我在 ...state.visibleElements 中已有的数组中和翻倍的价值

【讨论】:

    猜你喜欢
    • 2017-12-15
    • 2017-05-17
    • 2016-07-10
    • 2017-09-11
    • 1970-01-01
    • 2017-08-08
    • 2016-01-28
    • 1970-01-01
    • 2017-06-01
    相关资源
    最近更新 更多