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
React Hooks and Component
By zeroshine
React Hooks and Component
- 2,272