Merge pull request #276 from jorilallo/tom/less-render

Removes a react render loop when hovering over sidebar
This commit is contained in:
Jori Lallo
2017-09-27 23:58:03 -07:00
committed by GitHub
3 changed files with 52 additions and 40 deletions

View File

@ -53,39 +53,32 @@ type Props = {
} }
@observer class CollectionLink extends React.Component { @observer class CollectionLink extends React.Component {
@observable isHovering = false;
@observable menuOpen = false; @observable menuOpen = false;
handleHover = () => (this.isHovering = true);
handleBlur = () => {
if (!this.menuOpen) this.isHovering = false;
};
render() { render() {
const { history, collection, activeDocument, ui } = this.props; const { history, collection, activeDocument, ui } = this.props;
return ( return (
<DropToImport <StyledDropToImport
key={collection.id} key={collection.id}
history={history} history={history}
collectionId={collection.id} collectionId={collection.id}
activeClassName="activeDropZone" activeClassName="activeDropZone"
onMouseEnter={this.handleHover} menuOpen={this.menuOpen}
onMouseLeave={this.handleBlur}
> >
<SidebarLink key={collection.id} to={collection.url}> <SidebarLink key={collection.id} to={collection.url}>
<Flex justify="space-between"> <Flex justify="space-between">
{collection.name} {collection.name}
{(this.isHovering || this.menuOpen) && <CollectionAction>
<CollectionAction> <CollectionMenu
<CollectionMenu history={history}
history={history} collection={collection}
collection={collection} onShow={() => (this.menuOpen = true)}
onShow={() => (this.menuOpen = true)} onClose={() => (this.menuOpen = false)}
onClose={() => (this.menuOpen = false)} open={this.menuOpen}
/> />
</CollectionAction>} </CollectionAction>
</Flex> </Flex>
{collection.id === ui.activeCollectionId && {collection.id === ui.activeCollectionId &&
@ -101,7 +94,7 @@ type Props = {
))} ))}
</Children>} </Children>}
</SidebarLink> </SidebarLink>
</DropToImport> </StyledDropToImport>
); );
} }
} }
@ -156,14 +149,6 @@ const DocumentLink = observer((props: DocumentLinkProps) => {
); );
}); });
const Header = styled(Flex)`
font-size: 11px;
font-weight: ${fontWeight.semiBold};
text-transform: uppercase;
color: ${color.slate};
letter-spacing: 0.04em;
`;
const CollectionAction = styled.a` const CollectionAction = styled.a`
color: ${color.slate}; color: ${color.slate};
svg { opacity: .75; } svg { opacity: .75; }
@ -173,6 +158,26 @@ const CollectionAction = styled.a`
} }
`; `;
const StyledDropToImport = styled(DropToImport)`
${CollectionAction} {
display: ${props => (props.menuOpen ? 'inline' : 'none')};
}
&:hover {
${CollectionAction} {
display: inline;
}
}
`;
const Header = styled(Flex)`
font-size: 11px;
font-weight: ${fontWeight.semiBold};
text-transform: uppercase;
color: ${color.slate};
letter-spacing: 0.04em;
`;
const Children = styled(Flex)` const Children = styled(Flex)`
margin-left: 20px; margin-left: 20px;
`; `;

View File

@ -10,7 +10,7 @@ import Flex from 'components/Flex';
import { color, layout } from 'styles/constants'; import { color, layout } from 'styles/constants';
import { import {
collectionUrl, collectionUrl,
documentUpdateUrl, updateDocumentUrl,
documentMoveUrl, documentMoveUrl,
matchDocumentEdit, matchDocumentEdit,
matchDocumentMove, matchDocumentMove,
@ -60,7 +60,7 @@ type Props = {
@observable moveModalOpen: boolean = false; @observable moveModalOpen: boolean = false;
componentDidMount() { componentWillMount() {
this.loadDocument(this.props); this.loadDocument(this.props);
} }
@ -98,12 +98,15 @@ type Props = {
this.newDocument = newDocument; this.newDocument = newDocument;
} else { } else {
let document = this.getDocument(props.match.params.documentSlug); let document = this.getDocument(props.match.params.documentSlug);
if (document) {
this.props.ui.setActiveDocument(document);
}
await this.props.documents.fetch(props.match.params.documentSlug); if (document) {
document = this.document; this.props.documents.fetch(props.match.params.documentSlug);
this.props.ui.setActiveDocument(document);
} else {
document = await this.props.documents.fetch(
props.match.params.documentSlug
);
}
if (document) { if (document) {
this.props.ui.setActiveDocument(document); this.props.ui.setActiveDocument(document);
@ -113,7 +116,7 @@ type Props = {
// Update url to match the current one // Update url to match the current one
this.props.history.replace( this.props.history.replace(
documentUpdateUrl(this.props.match.url, document.url) updateDocumentUrl(props.match.url, document.url)
); );
} else { } else {
// Render 404 with search // Render 404 with search
@ -218,9 +221,9 @@ type Props = {
render() { render() {
const isNew = this.props.newDocument; const isNew = this.props.newDocument;
const isMoving = this.props.match.path === matchDocumentMove; const isMoving = this.props.match.path === matchDocumentMove;
const isFetching = !this.document;
const titleText = get(this.document, 'title', '');
const document = this.document; const document = this.document;
const isFetching = !document;
const titleText = get(document, 'title', '');
if (this.notFound) { if (this.notFound) {
return this.renderNotFound(); return this.renderNotFound();

View File

@ -34,10 +34,14 @@ export function documentMoveUrl(doc: Document): string {
* Replace full url's document part with the new one in case * Replace full url's document part with the new one in case
* the document slug has been updated * the document slug has been updated
*/ */
export function documentUpdateUrl(oldUrl: string, newUrl: string): string { export function updateDocumentUrl(oldUrl: string, newUrl: string): string {
// Update url to match the current one // Update url to match the current one
const urlParts = oldUrl.split('/'); const urlParts = oldUrl.trim().split('/');
return [newUrl, urlParts.slice(3)].join('/'); const actions = urlParts.slice(3);
if (actions[0]) {
return [newUrl, actions].join('/');
}
return newUrl;
} }
export function newDocumentUrl(collection: Collection): string { export function newDocumentUrl(collection: Collection): string {