react项目代码比对插件使用优化记录

1,753 阅读1分钟

背景

日常开发中,少不了需要展示代码diff、日志diff等不同比对内容的场景,找到一个比较好用的插件 react-code-diff-lite 为了达到一些更好的交互体验效果,比如同步滚动,内容超长加滚动条效果,需要在原有的基础上做出一点小优化。

优化

import React, { useEffect, useState } from 'react';
import useStore from 'xxx/xxx';// 按照实际情况使用
import CodeDiff from 'react-code-diff-lite';
import './index.less';

function ShowCodeDiff(props) {
    const [formatOldStr, setFormatOldStr] = useState('');
    const [formatNewStr, setFormatNewStr] = useState('');
    const themeMode = useStore(state => state.themeMode); // 取决于实际使用全局theme数据存放在什么地方,这里相应改动
    useEffect(() => {
        const timeOutId = setTimeout(() => {
            addScroll(); // 关键
        }, 500);
        return () => {
            clearTimeout(timeOutId);
            removeScroll();
        };
    }, []);

    useEffect(() => {
        const { oldStr = '', newStr = '' } = props;
        try {
            setFormatOldStr(JSON.stringify(JSON.parse(oldStr), null, '\t'));
            setFormatNewStr(JSON.stringify(JSON.parse(newStr), null, '\t'));
        } catch (error) {
            setFormatOldStr(oldStr);
            setFormatNewStr(newStr);
        }
    }, [props.oldStr, props.newStr]);

    const addScroll = () => {
        const scrollContainers = document.getElementsByClassName('d2h-file-side-diff');
        if (scrollContainers && scrollContainers.length > 1) {
            const scrolls = Array.from(scrollContainers);
            scrolls.forEach(scrollItem => {
                scrollItem.addEventListener('scroll', syncScroll);
            });
        }
    };

    const removeScroll = () => {
        const scrollContainers = document.getElementsByClassName('d2h-file-side-diff');
        if (scrollContainers && scrollContainers.length > 1) {
            const scrolls = Array.from(scrollContainers);
            scrolls.forEach(scrollItem => {
                scrollItem.removeEventListener('scroll', this.syncScroll);
            });
        }
    };

    // 同步两侧代码滚动方法
    const syncScroll = e => {
        const leftValue = e.target.scrollLeft;
        const topValue = e.target.scrollTop;
        Array.from(document.getElementsByClassName('d2h-file-side-diff')).forEach(item => {
            item.scrollLeft = leftValue; // 横向滚动同步
            item.scrollTop = topValue; // 纵向滚动同步
        });
    };
    const { configOptions = {} } = props;
    const { context = 10, outputFormat = 'side-by-side', ...restConfig } = configOptions;
    return (
        <div className="codeDiff" style={{ maxHeight: 420 }}>
            <CodeDiff
                oldStr={formatOldStr}
                newStr={formatNewStr}
                context={context}
                outputFormat={outputFormat}
                theme={themeMode}
                {...restConfig}
            />
        </div>
    );
}

export default ShowCodeDiff;

index.less

.codeDiff {
    .d2h-file-side-diff {
        position: relative;
        max-height: '100%';
        position: relative;
        overflow: auto;

        &:first-child {
            border-right: solid 1px #d8d8d8;
            z-index: 1;
        }
    }
}

官网demo是可以同步滚动的,但是没找到对应生效的配置方法,就只能自己动手解决了。