Skip to content

Instantly share code, notes, and snippets.

@otakustay
Created March 9, 2018 04:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save otakustay/7aac98708aff358b8e59c61e1f765452 to your computer and use it in GitHub Desktop.
Save otakustay/7aac98708aff358b8e59c61e1f765452 to your computer and use it in GitHub Desktop.
state management in react
import {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {createSelector} from 'reselect';
import {parseDiff, addStubHunk, expandFromRawCode, Diff, Hunk} from 'react-diff-view';
import {push} from 'san-update/fp';
import {diffLines, formatLines} from 'unidiff';
import {property} from 'lodash/fp';
import 'react-diff-view/index.css';
import HunkHeader from './HunkHeader';
export default class TextDiff extends PureComponent {
static propTypes = {
oldText: PropTypes.string.isRequired,
newText: PropTypes.string.isRequired
};
state = {
expandedBlocks: []
};
computeRawHunks = createSelector(
property('oldText'), property('newText'),
(oldText, newText) => {
const paddingMetaInfo = 'diff --git a/a b/b';
const paddingIndexInfo = 'index 1111111..2222222 100644';
const diffBody = formatLines(diffLines(oldText, newText));
const diffText = [paddingMetaInfo, paddingIndexInfo, diffBody].join('\n');
return parseDiff(diffText)[0].hunks;
}
);
computeHunks = createSelector(
this.computeRawHunks, property('oldText'), property('expandedBlocks'),
(rawHunks, oldText, expandedBlocks) => {
const newHunks = expandedBlocks.reduce(
(hunks, blockIndex) => {
const previousHunk = rawHunks[blockIndex - 1];
const nextHunk = rawHunks[blockIndex];
const start = previousHunk ? previousHunk.oldStart + previousHunk.oldLines : 1;
const end = nextHunk ? nextHunk.oldStart : Infinity;
return expandFromRawCode(hunks, oldText, start, end);
},
rawHunks
);
return addStubHunk(newHunks, oldText);
}
);
expandBlock = blockIndex => this.setState(push('expandedBlocks', blockIndex));
render() {
const hunks = this.computeHunks({...this.props, ...this.state});
const renderHunk = (hunk, i) => {
const header = hunk.oldStart === 1 ? null : <HunkHeader hunkIndex={i} onClick={this.expandBlock} />;
return <Hunk key={hunk.content} hunk={hunk} header={header} />;
};
return (
<Diff viewType="split">
{hunks.map(renderHunk)}
</Diff>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment