我正在开发 react js 应用程序,我使用“react-dragula”拖放列表项。我在父包装组件中显示子组件 html 的预览。删除一个元素后,我的 html 无法正确呈现。我不知道是因为 Dragula 还是有其他问题。删除列表项后,我将根据元素索引更新列表值并更新状态并重新渲染子组件。但它向我展示了旧的 html,它没有使用父组件返回的更新道具重新渲染子组件的 html。
这是我的代码::
class App extends React.Component {
drake = null;
socialContainers = [];
/** lifecycle method */
componentDidMount() {
this.drake = Dragula(this.socialContainers, {
isContainer: function (el) {
return (el.id === 'social-container');
},
moves: function (el, source, handle, sibling) {
return (handle.id === "socialSortBtn");
},
accepts: function (el, target, source, sibling) {
return (target.id === 'social-container' && source.id === 'social-container');
},
});
this.drake.on('drop', (el, target, source, sibling) => {
el.style.cursor = "grab";
let oldIndex = el.dataset.index
let type = el.dataset.type
let iconIndx = Array.prototype.indexOf.call(target.children, el);
let targetIndex = iconIndx > 0 ? iconIndx : 0;
if (type) {
let content = {}
content.reOrder = true;
content.oldIndex = oldIndex;
this.props.callback(content, 'content', targetIndex)
}
});
this.drake.on('drag', (el, source) => {
el.style.cursor="grabbing";
})
}
updateLinkText(val, index) {
const { data, callback } = this.props;
let textParsedHtml = new DOMParser().parseFromString(data.content[index].text, 'text/html');
if (textParsedHtml.getElementsByTagName("a")[0]) {
textParsedHtml.getElementsByTagName("a")[0].innerHTML = val;
}
let content = {}
content.changeLinkTxt = true
content.linkText = val
content.linkTextHtml = textParsedHtml.body.innerHTML
//update content
callback(content, 'content', index)
}
onSelectShareOpt(selectedVal, selectedIndx, event) {
event.stopPropagation();
let socialObj = socialShareArr.find((obj) => obj.value === selectedVal)
if (socialObj) {
let htmlObj = this.getHTMLObj(socialObj);
let content = {}
content.active_social_icons = socialObj
if(htmlObj) { content.content = htmlObj }
// update content
this.props.callback(content, 'content', selectedIndx)
}
}
isIconDisabled = (data, val) => {
let found = false;
found = data.some(function (obj) {
if (obj.value === val) {
return true;
}
return false;
});
return found;
}
renderSocialIcons(dragulaDecoratorRef) {
const { data } = this.props;
let socialIcons = data.activeIcons;
if (!socialIcons) {
return null
}
return (
<Fragment>
{socialIcons && socialIcons.length > 0 && socialIcons.map((activeIcon, index) => (
<li key={index} data-index={index} data-type={activeIcon.value} className="mb-30">
<div className="mr-2">
<button data-toggle="tooltip" title="Drag to reorder" className="btn btn-primary btn-sm btn-icon" id="dragBtn"><span id="socialSortBtn" className="material-icons m-0">drag_indicator</span>
</button>
</div>
<div className="mb-30">
<img className="mr-2" src={activeIcon.icon} alt="social-icon" width="36" height="36" />
<FormControl
value={activeIcon.value}
as="select"
onChange={e => this.onSelectShareOpt(e.target.value, index, e)}
custom
size=''
>
{socialShareArr && socialShareArr.map((option, index) => (
<option
key={index}
disabled={this.isIconDisabled(socialIcons, option.value)}
value={option.value}
>
{option.label}
</option>
))}
</FormControl>
</div>
<Form.Group>
<Form.Label>Link Text</Form.Label>
<TextInput
value={activeIcon.linkText}
onChange={(e) => this.updateLinkText(e.target.value, index)}
wrapperClass="mx-10 mb-0"
/>
</Form.Group>
</li>
))}
</Fragment>
);
}
// main function
render() {
const { data } = this.props;
const dragulaDecoratorRef = (componentBackingInstance) => {
if (componentBackingInstance) {
this.socialContainers.push(componentBackingInstance)
}
};
return (
<Fragment>
{data &&
<AppCard>
<Card.Body>
<div className="social-opt-container">
<ul id='social-container' ref={dragulaDecoratorRef}>
{this.renderSocialIcons(dragulaDecoratorRef)}
</ul>
</div>
</Card.Body>
</AppCard>
}
</Fragment>
)
}
}
export { App }
我还尝试删除“”的 innerHTML,然后返回新结构,但在这种情况下,它在 html 中不返回任何内容。请检查一下为什么会出现此问题。