Skip to content

Commit

Permalink
fix: improve performance in the sortable stress test example
Browse files Browse the repository at this point in the history
  • Loading branch information
darthtrevino committed Jun 7, 2019
1 parent 6630373 commit a1584d9
Show file tree
Hide file tree
Showing 20 changed files with 83 additions and 79 deletions.
1 change: 1 addition & 0 deletions package.json
Expand Up @@ -74,6 +74,7 @@
"tslint": "^5.17.0",
"tslint-config-prettier": "^1.18.0",
"tslint-react": "^4.0.0",
"tslint-react-hooks": "^2.1.0",
"typescript": "^3.5.1"
},
"jest": {
Expand Down
8 changes: 3 additions & 5 deletions packages/examples-hooks/src/00-chessboard/index.tsx
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
import Board from './Board'
import { observe } from './Game'

Expand All @@ -16,12 +16,10 @@ const containerStyle: React.CSSProperties = {
* The Chessboard Tutorial Application
*/
const ChessboardTutorialApp: React.FC = () => {
const [knightPos, setKnightPos] = React.useState<[number, number]>([1, 7])
const [knightPos, setKnightPos] = useState<[number, number]>([1, 7])

// the observe function will return an unsubscribe callback
React.useEffect(() =>
observe((newPos: [number, number]) => setKnightPos(newPos)),
)
useEffect(() => observe((newPos: [number, number]) => setKnightPos(newPos)))
return (
<div>
<h1>EXPERIMENTAL API</h1>
Expand Down
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React, { useState, useCallback } from 'react'
import Container from './Container'
import CustomDragLayer from './CustomDragLayer'

Expand All @@ -11,11 +11,11 @@ const DragAroundCustomDragLayer: React.FC = () => {
const [snapToGridAfterDrop, setSnapToGridAfterDrop] = useState(false)
const [snapToGridWhileDragging, setSnapToGridWhileDragging] = useState(false)

const handleSnapToGridAfterDropChange = React.useCallback(() => {
const handleSnapToGridAfterDropChange = useCallback(() => {
setSnapToGridAfterDrop(!snapToGridAfterDrop)
}, [snapToGridAfterDrop])

const handleSnapToGridWhileDraggingChange = React.useCallback(() => {
const handleSnapToGridWhileDraggingChange = useCallback(() => {
setSnapToGridWhileDragging(!snapToGridWhileDragging)
}, [snapToGridWhileDragging])

Expand Down
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import {
__EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__,
XYCoord,
Expand Down Expand Up @@ -28,7 +28,7 @@ export interface ContainerState {
}

const Container: React.FC<ContainerProps> = ({ hideSourceOnDrag }) => {
const [boxes, setBoxes] = React.useState<{
const [boxes, setBoxes] = useState<{
[key: string]: {
top: number
left: number
Expand Down
11 changes: 5 additions & 6 deletions packages/examples-hooks/src/02-drag-around/naive/index.tsx
@@ -1,12 +1,11 @@
import React from 'react'
import React, { useState, useCallback } from 'react'
import Container from './Container'

export default function DragAroundNaive() {
const [hideSourceOnDrag, setHideSourceOnDrag] = React.useState(true)
const toggle = React.useCallback(
() => setHideSourceOnDrag(!hideSourceOnDrag),
[hideSourceOnDrag],
)
const [hideSourceOnDrag, setHideSourceOnDrag] = useState(true)
const toggle = useCallback(() => setHideSourceOnDrag(!hideSourceOnDrag), [
hideSourceOnDrag,
])

return (
<div>
Expand Down
@@ -1,5 +1,5 @@
// tslint:disable max-classes-per-file
import React from 'react'
import React, { useState, useCallback } from 'react'
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ } from 'react-dnd'
import Colors from './Colors'
import { DragItem } from './interfaces'
Expand Down Expand Up @@ -64,10 +64,8 @@ export interface StatefulTargetBoxState {
lastDroppedColor: string | null
}
const StatefulTargetBox: React.FC = props => {
const [lastDroppedColor, setLastDroppedColor] = React.useState<string | null>(
null,
)
const handleDrop = React.useCallback(
const [lastDroppedColor, setLastDroppedColor] = useState<string | null>(null)
const handleDrop = useCallback(
(color: string) => setLastDroppedColor(color),
[],
)
Expand Down
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ } from 'react-dnd'
import ItemTypes from './ItemTypes'
const {
Expand Down Expand Up @@ -31,8 +31,8 @@ export interface DustbinState {
}

const Dustbin: React.FC<DustbinProps> = ({ greedy, children }) => {
const [hasDropped, setHasDropped] = React.useState(false)
const [hasDroppedOnChild, setHasDroppedOnChild] = React.useState(false)
const [hasDropped, setHasDropped] = useState(false)
const [hasDroppedOnChild, setHasDroppedOnChild] = useState(false)

const [{ isOver, isOverCurrent }, drop] = useDrop({
accept: ItemTypes.BOX,
Expand Down
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ } from 'react-dnd'
import Card from './Card'
import update from 'immutability-helper'
Expand Down Expand Up @@ -48,7 +48,7 @@ const ITEMS = [
]

const Container: React.FC = () => {
const [cards, setCards] = React.useState(ITEMS)
const [cards, setCards] = useState(ITEMS)
const moveCard = (id: string, atIndex: number) => {
const { card, index } = findCard(id)
setCards(
Expand Down
15 changes: 9 additions & 6 deletions packages/examples-hooks/src/04-sortable/stress-test/Card.tsx
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useMemo, useRef } from 'react'
import { __EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__ } from 'react-dnd'
import ItemTypes from './ItemTypes'
const {
Expand All @@ -21,12 +21,15 @@ export interface CardProps {
}

const Card: React.FC<CardProps> = ({ id, text, moveCard }) => {
const ref = React.useRef(null)
const ref = useRef(null)
const [{ isDragging }, connectDrag] = useDrag({
item: { id, type: ItemTypes.CARD },
collect: (monitor: any) => ({
isDragging: monitor.isDragging(),
}),
collect: (monitor: any) => {
const result = {
isDragging: monitor.isDragging(),
}
return result
},
})

const [, connectDrop] = useDrop({
Expand All @@ -41,7 +44,7 @@ const Card: React.FC<CardProps> = ({ id, text, moveCard }) => {
connectDrag(ref)
connectDrop(ref)
const opacity = isDragging ? 0 : 1
const containerStyle = React.useMemo(() => ({ ...style, opacity }), [opacity])
const containerStyle = useMemo(() => ({ ...style, opacity }), [opacity])
return (
<div ref={ref} style={containerStyle}>
{text}
Expand Down
31 changes: 17 additions & 14 deletions packages/examples-hooks/src/04-sortable/stress-test/Container.tsx
Expand Up @@ -12,27 +12,30 @@ export interface ContainerState {
cardsByIndex: any[]
}

function buildCardData() {
const cardsById: { [key: string]: any } = {}
const cardsByIndex = []

for (let i = 0; i < 1000; i += 1) {
const card = { id: i, text: name.findName() }
cardsById[card.id] = card
cardsByIndex[i] = card
}

return {
cardsById,
cardsByIndex,
}
}

export default class Container extends React.Component<{}, ContainerState> {
// tslint:disable-next-line ban-types
private pendingUpdateFn: any
private requestedFrame: number | undefined

constructor(props: {}) {
super(props)

const cardsById: { [key: string]: any } = {}
const cardsByIndex = []

for (let i = 0; i < 1000; i += 1) {
const card = { id: i, text: name.findName() }
cardsById[card.id] = card
cardsByIndex[i] = card
}

this.state = {
cardsById,
cardsByIndex,
}
this.state = buildCardData()
}

public componentWillUnmount() {
Expand Down
6 changes: 3 additions & 3 deletions packages/examples-hooks/src/04-sortable/stress-test/index.tsx
@@ -1,10 +1,10 @@
import React from 'react'
import React, { useState, useEffect } from 'react'
import Container from './Container'

export default function SortableStressTest() {
// Avoid rendering on server because the big data list is generated
const [shouldRender, setShouldRender] = React.useState(false)
const [shouldRender, setShouldRender] = useState(false)
// Won't fire on server.
React.useEffect(() => setShouldRender(true), [])
useEffect(() => setShouldRender(true), [])
return <>{shouldRender && <Container />}</>
}
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useCallback } from 'react'
import {
__EXPERIMENTAL_DND_HOOKS_THAT_MAY_CHANGE_AND_BREAK_MY_BUILD__,
ConnectDragSource,
Expand All @@ -25,8 +25,8 @@ interface ChildProps {
drag: ConnectDragSource
}
const Child: React.FC<ChildProps> = ({ drag, children }) => {
const [open, setOpen] = React.useState(true)
const toggle = React.useCallback(() => setOpen(!open), [open])
const [open, setOpen] = useState(true)
const toggle = useCallback(() => setOpen(!open), [open])

return (
<div
Expand Down
@@ -1,4 +1,4 @@
import React, { useState } from 'react'
import React, { useState, useCallback } from 'react'
import Container from './Container'
import CustomDragLayer from './CustomDragLayer'

Expand All @@ -11,11 +11,11 @@ const DragAroundCustomDragLayer: React.FC = () => {
const [snapToGridAfterDrop, setSnapToGridAfterDrop] = useState(false)
const [snapToGridWhileDragging, setSnapToGridWhileDragging] = useState(false)

const handleSnapToGridAfterDropChange = React.useCallback(() => {
const handleSnapToGridAfterDropChange = useCallback(() => {
setSnapToGridAfterDrop(!snapToGridAfterDrop)
}, [snapToGridAfterDrop])

const handleSnapToGridWhileDraggingChange = React.useCallback(() => {
const handleSnapToGridWhileDraggingChange = useCallback(() => {
setSnapToGridWhileDragging(!snapToGridWhileDragging)
}, [snapToGridWhileDragging])

Expand Down
@@ -1,4 +1,4 @@
import React from 'react'
import React, { useState, useCallback } from 'react'
import { DragSource, ConnectDragSource } from 'react-dnd'

interface ParentProps {
Expand Down Expand Up @@ -30,8 +30,8 @@ interface ChildProps {
}

const Child: React.FC<ChildProps> = ({ connect, children }) => {
const [open, setOpen] = React.useState(true)
const toggle = React.useCallback(() => setOpen(!open), [open])
const [open, setOpen] = useState(true)
const toggle = useCallback(() => setOpen(!open), [open])

return (
<div
Expand Down
1 change: 0 additions & 1 deletion packages/react-dnd/src/hooks/internal/drag.ts
Expand Up @@ -75,7 +75,6 @@ export function useDragHandler<
}, [])

useEffect(function registerHandler() {
// console.log('Register Handler')
const [handlerId, unregister] = registerSource(
spec.current.item.type,
handler,
Expand Down
2 changes: 0 additions & 2 deletions packages/react-dnd/src/hooks/internal/drop.ts
Expand Up @@ -34,7 +34,6 @@ export function useDropHandler<

// Can't use createSourceFactory, as semantics are different
const handler = useMemo(() => {
// console.log('create drop target handler')
return {
canDrop() {
const { canDrop } = spec.current
Expand All @@ -57,7 +56,6 @@ export function useDropHandler<

useEffect(
function registerHandler() {
// console.log('register droptarget handler')
const [handlerId, unregister] = registerTarget(
spec.current.accept,
handler,
Expand Down
24 changes: 10 additions & 14 deletions packages/react-dnd/src/hooks/internal/useCollector.ts
@@ -1,6 +1,6 @@
// declare var require: any
// const shallowEqual = require('shallowequal')
import { useState } from 'react'
declare var require: any
const shallowEqual = require('shallowequal')
import { useState, useCallback } from 'react'

/**
*
Expand All @@ -15,19 +15,15 @@ export function useCollector<T, S>(
): [S, () => void] {
const [collected, setCollected] = useState(() => collect(monitor))

const updateCollected = () => {
const updateCollected = useCallback(() => {
const nextValue = collect(monitor)
// TODO: we need this shallowequal check to work
// so that we can operate performantly, but the examples
// are broken with it in currently

// if (!shallowEqual(collected, nextValue)) {
setCollected(nextValue)
if (onUpdate) {
onUpdate()
if (!shallowEqual(collected, nextValue)) {
setCollected(nextValue)
if (onUpdate) {
onUpdate()
}
}
// }
}
}, [collected, monitor, onUpdate])

return [collected, updateCollected]
}
5 changes: 2 additions & 3 deletions packages/react-dnd/src/hooks/internal/useMonitorOutput.ts
Expand Up @@ -15,12 +15,11 @@ export function useMonitorOutput<Monitor extends HandlerManager, Collected>(
if (handlerId == null) {
return undefined
}
const unsubscribe = monitor.subscribeToStateChange(updateCollected, {
return monitor.subscribeToStateChange(updateCollected, {
handlerIds: [handlerId],
})
return unsubscribe
},
[monitor],
[monitor, updateCollected],
)

return collected
Expand Down
7 changes: 6 additions & 1 deletion tslint.json
@@ -1,6 +1,11 @@
{
"defaultSeverity": "error",
"extends": ["tslint:recommended", "tslint-react", "tslint-config-prettier"],
"extends": [
"tslint:recommended",
"tslint-react",
"tslint-react-hooks",
"tslint-config-prettier"
],
"jsRules": {},
"rules": {
// We handle this manually
Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Expand Up @@ -15827,6 +15827,11 @@ tslint-config-prettier@^1.18.0:
resolved "https://registry.yarnpkg.com/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz#75f140bde947d35d8f0d238e0ebf809d64592c37"
integrity sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==

tslint-react-hooks@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tslint-react-hooks/-/tslint-react-hooks-2.1.0.tgz#cc9841da0cef20d3527c8d16412f029c33767898"
integrity sha512-ccjyguEHGEU5rXikLDaQ6kT1AVo3C0HV8gi2MIJc7SbYAXjbzJkpbs4IXulgfqdEY1T6RnNSuGhyXg+2jTm5Bg==

tslint-react@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/tslint-react/-/tslint-react-4.0.0.tgz#b4bb4c01c32448cb14d23f143a2f5e4989bb961e"
Expand Down

0 comments on commit a1584d9

Please sign in to comment.