在反应中处理"outside react" DOM 更改



我有一个下拉列表,它被实例化为物化(无关紧要,可以是JQuery或任何其他(,物化在DOM中插入react不知道的元素。这导致如果我将此组件用作其他组件的子组件并有条件地渲染它,react将抛出异常:

React DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is not a child of this node

这是我的dropdowm组件,当它没有初始化时用实体化;

<div class="input-field col s2">
<select id="defaultOption">
/* options. Not relevant */
</select></div>
</div>

但是,如果初始化(这是从下拉列表中需要的(,我会将物化元素插入DOM中,但不会插入虚拟DOM中:

<div class="input-field col s2">
<div class="select-wrapper">        ------>//materialize wrapper
....                            ------>//other materialize added nodes
<select id="defaultOption">     ------>//original select, root node of the component
/* options. Not relevant */
</select></div>
</div>
</div>

在产生错误的地方进行调试,正是在做出反应时,尝试删除function removeChild(parentInstance, child)函数中的<select id="defaultOption">,因此DOM层次结构中的不匹配似乎清楚地导致了问题。

似乎与JQuery的这个非常相似。

如何更新虚拟DOM中插入的节点,使DOM和虚拟DOM之间不会出现不匹配?

我在组件代码下面发布,在那里你可以看到组件是如何在unseEffect()中初始化的,以防有一些帮助建议:

import React, { useEffect, useState, useRef } from "react";
const makeOptionItem = function(value: string, key: number) {
return <option key={key} value={key}>{value}</option>;
};
const MaterializeDropdown = (props: { options: string[], placeholderText:string, onOptionSelect?: (selectedOption:string) => void } ) => {
useEffect(() => {
const select = selectRef.current;      
if (select) M.FormSelect.init(select, {
dropdownOptions: {
inDuration: 300,
outDuration: 225,
constrainWidth: false, // Does not change width of dropdown to that of the activator
hover: false, // Activate on hover
alignment: 'left', // Displays dropdown with edge aligned to the left of button 
coverTrigger: true
}
});
}, []);

return(
<select id="defaultOption" defaultValue=''>
<option value='' disabled>{placeholderText}</option>
{props.options.map(makeOptionItem)}
</select>
);
}
export default MaterializeDropdown;

在返回中用div封装select只会解决问题:

return(
<div>
<select id="defaultOption" defaultValue='' onChange={(event) => handleOnChange(event)} ref={selectRef}>
<option value='' disabled>{placeholderText}</option>
{props.options.map(makeOptionItem)}
</select>
</div>

);

相关内容

最新更新