React Hooks and Component

About me

陳冠霖
Jason Chen

Software engineer in
Yahoo Taiwan EC

 

 

 

       slack: gchen02

       https://fb.me/Jason.GuanLin.Chen

       https://medium.com/@as790726
       Comics Scroller Chrome extension
 

OOP
Stateful Class

FP
Pure

Function

React Component is described mostly by

React Today and Tomorrow React conf 2018

What in React still sucks

What in React still sucks

  • giant component
  • confusing class
  • reuse logic

Giant Component

class ActInfo extends Component {
  componentDidMount() {
    this.fetchActInfo()
    this.startTimer()
    this.fixWindow()
  }

  componentWillUnmount() {
    this.cancelFetchActInfo()
    this.clearTimer()
    this.unFixWindow()
  }
  
  componentDidUpdate(prevProps) {
    if(this.props.aaa !== prevProps.aaa) {
      ...
    }
  }
}
  • logic is separated in mount and update lifecycle
  • watch some props in update lifecycle

What in React still suck

  • giant component
  • confusing class
  • reuse logic

Confusing class

  • binding this in class is confusing for beginner
  • function component to class component
  • hard to optimize for compiler

What in React still suck

  • giant component
  • confusing class
  • reuse logic

React Reuse Logic Pattern

  • createClass and Mixins
  • higher order component
  • render props

Problems happen when these pattern scale

const App = React.createClass({
  // Use the mixin!
  mixins: [ 
    MouseMixin,
    toolTipsMixin,
    popUpMixin
  ],
  
  render() {
    const { x, y } = this.state

    return (
      <div 
        style={{ height: '100%' }} 
        onMouseMove={this.handleMouseMove}
      >
        <h1>The mouse position is ({x}, {y})</h1>
      </div>
    )
  }
})

createClass and mixins

  • ECMAScript 2015 class not support
  • where attribute coming from is confusing
  • lifecycle hijack
  • attribute naming  conflict and override

Mixins Consider Harmful

Dan Abramov in react official blog 

Higher Order Component

const ComponentA = ({ doSomeThing }) => (
  <div onClick={doSomeThing} />
)

compose(
  withRouter
  withContext
  connect
  withI13n
  withI18n
)(ComponentA)
  • where props coming from is confusing
  • props naming conflict and override

Never write another Hoc
by Michael Jackson Phoenix React meetup

Render Props

const App = () => (
  <Tooltip>
   {(renderToolTip) => (
      <MouseHover>
        {(handleMouseHover, isMouseHover) => (
          <div
           onMouseHover={handleMouseHover}
           className={
             isMouseHover ? style.active : style.normal
           } 
          >
           {renderToolTip()}
          </div>
        )}
      <MouseHover>
   )}
  </Tooltip>
)

What in react still sucks

  • giant Component
    • logic is separated in mount and update lifecycle
    • watch some props in update lifecycle
  • confusing class
    • this binding is confusing for beginner
    • hard for compiler optimize
    • functional component to class component
  • reuse logic
    • declarative and explicit dependency
    • naming conflict
    • wrapper hell + multiple createElement call

What are React hooks

make Function Component great again

useState hooks

const Cmp = () => {
  const [state, setState] = useState(initialValue)
  return (
    <div onClick={() => setState(value)}>
      {state}
    </div>
  )
}

useEffect hooks

const Cmp = () => {
  useEffect(() => {
    const timeout = setTimeout(() => {}, 10000)
    return () => clearTimeout(timeout)
  })
  return (
    <div>
      {state}
    </div>
  )
}

rewrite a Carousel Example

custom hook demo

minify comparison

hoc

babel loose compile 3.8KB
minify 2.5KB
0.66%

hooks
babel loose compile 1.4KB

minify  684 Byte

0.48%

What in react still sucks

  • giant Component
    • logic is separated in mount and update lifecycle
    • watch some props in update lifecycle
  • confusing class
    • this binding is confusing for beginner
    • hard for compiler optimize
    • functional component => class component
  • reuse logic
    • wrapper hell + multiple createElement call
    • declarative and explicit dependency
    • naming conflict

😀

😀

😀

😀

😀

😀

😀

😀

More hooks

  • Basic Hooks

    • useState
    • useEffect
    • useContext
  • Additional Hooks

    • useReducer
    • useCallback
    • useMemo
    • useRef
    • useImperativeMethods
    • useDebugValue
    • useLayoutEffect

How hooks work

pseudo code

let hooks = null;

export function useHook() {
  hooks.push(hookData); 
}

function reactInternalRenderAComponentMethod(component) {
  hooks = [];
  component();
  let hooksForThisComponent = hooks;
  hooks = null;
}

Rule of hooks

  • hooks should be the same order in every rendering
  • no conditional hook
  • only call hooks inside component and custom hooks
  • eslint-plugin-react-hooks

state linked list

setter linked list

State 1

setter 1

State 2

setter 2

State 3

setter 3

function with hook vs
Class Component

an Apply job example

function in Component capture all props and state for it own render

useCallback & useEffect

useEffect(() => {

}, [listenOuter1, listenOuter2])



const memoizedCallback = useCallback(() => {

}, [listenOuter1, listenOuter2])

Frequently Asked Questions

How to learn hooks?

how about testing

🚧 Enzyme

class Component is bad and will be deprecated

rewrite everything with hooks?

will hooks replace redux?

will context api replace redux?

React-Redux v7 is rewritten in hooks

One more thing

OOP
Stateful Class

FP
Pure

Function

React Component is described mostly by

Stateful Class Model

🤔 receive props

🤔 pure render

🤔 no direct instantiation

 

Pure Function Model

🤔 local mutable state 

class Item extends Component {
  state = { isOn: false }
}
const Item = ({ text }) => (
  <div>{text}</div>
)

OOP
stateful
Class

FP
pure
function

stateful function with effect

React Component is described mostly by

Made with Slides.com