1

我正在开发 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 中不返回任何内容。请检查一下为什么会出现此问题。

4

0 回答 0