Upgrade to Pro — share decks privately, control downloads, hide ads and more …

the new react

the new react

Raphael Amorim

November 06, 2018
Tweet

More Decks by Raphael Amorim

Other Decks in Programming

Transcript

  1. The
    New
    React
    Lifecycles
    @raphamorims

    View Slide

  2. Hi, I’m
    Raphael
    アモリム

    View Slide

  3. View Slide

  4. View Slide

  5. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    What’s New?

    View Slide

  6. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    What’s New?

    View Slide

  7. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    What’s New?

    View Slide

  8. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    What’s New?

    View Slide

  9. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    • Strict Mode
    What’s New?

    View Slide

  10. • Official Context API
    • createRef API
    • forwardRef API
    • Component Lifecycle Changes
    • Strict Mode
    • React Hooks
    What’s New?

    View Slide

  11. New context API
    const ThemeContext = React.createContext('light');

    View Slide

  12. New context API
    const ThemeContext = React.createContext('light');
    class ThemeProvider extends React.Component {
    state = {theme: 'light'};
    render() {
    return (

    {this.props.children}

    );
    }
    }

    View Slide

  13. New context API
    class ThemedButton extends React.Component {
    render() {
    return (

    {theme => }

    );
    }
    }

    View Slide

  14. createRef
    class InputComponent extends Component {
    constructor(props) {
    super(props);
    this.inputRef = React.createRef();
    }
    componentDidMount() {
    this.inputRef.current.focus();
    }
    render() {
    return ;
    }
    }

    View Slide

  15. Callback refs will continue to be supported in
    addition to the new createRef API.
    You don’t need to replace callback refs in your
    components.

    View Slide

  16. const FancyButton = React.forwardRef((props, ref) => (

    {props.children}

    ));
    // You can now get a ref directly to the DOM button:
    const ref = React.createRef();
    Click me!;
    fowardRef

    View Slide

  17. import React from 'react';
    function Application() {
    return (










    );
    }
    StrictMode
    * StrictMode is a tool for highlighting potential problems in an application.
    Like Fragment, StrictMode does not render any visible UI. 

    It activates additional checks and warnings for its descendants.

    View Slide

  18. • Identifying components with unsafe lifecycles

    • Warning about legacy string ref API usage

    • Warning about deprecated findDOMNode usage

    • Detecting unexpected side effects

    • Detecting legacy context API
    StrictMode

    View Slide

  19. StrictMode

    View Slide

  20. StrictMode
    You probably are like this:

    View Slide

  21. StrictMode
    No one likes a lint error,
    but it is useful.

    View Slide

  22. New and the Old React Lifecycles

    View Slide

  23. Legacy lifecycles will continue to work until version 17.
    New and the Old React Lifecycles

    View Slide

  24. • componentWillMount
    • componentWillReceiveProps
    • componentWillUpdate
    Deprecated now and will be removed in React 17

    View Slide

  25. • UNSAFE_componentWillMount
    • UNSAFE_componentWillReceiveProps
    • UNSAFE_componentWillUpdate
    Works on React 17
    * Works with some bugs

    View Slide

  26. • getDerivedStateFromProps
    • getSnapshotBeforeUpdate
    New lifecycles

    View Slide

  27. getDerivedStateFromProps

    View Slide

  28. getDerivedStateFromProps
    // Before
    class ExampleComponent extends React.Component {
    state = {
    isScrollingDown: false,
    };
    componentWillReceiveProps(nextProps) {
    if (this.props.currentRow !== nextProps.currentRow) {
    this.setState({
    isScrollingDown:
    nextProps.currentRow > this.props.currentRow,
    });
    }
    }
    }

    View Slide

  29. // After
    class ExampleComponent extends React.Component {
    // Initialize state in constructor,
    // Or with a property initializer.
    state = {
    isScrollingDown: false,
    lastRow: null,
    };
    static getDerivedStateFromProps(props, state) {
    if (props.currentRow !== state.lastRow) {
    return {
    isScrollingDown: props.currentRow > state.lastRow,
    lastRow: props.currentRow,
    };
    }
    // Return null to indicate no change to state.
    return null;
    }
    }

    View Slide

  30. getSnapshotBeforeUpdate

    View Slide

  31. // Before
    class ScrollingList extends Component {
    listRef = null;
    previousScrollOffset = null;
    componentWillUpdate(nextProps, nextState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (this.props.list.length < nextProps.list.length) {
    this.previousScrollOffset =
    this.listRef.scrollHeight - this.listRef.scrollTop;
    }
    }
    componentDidUpdate(prevProps, prevState) {
    // If previousScrollOffset is set, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    if (this.previousScrollOffset !== null) {
    this.listRef.scrollTop =
    this.listRef.scrollHeight -
    this.previousScrollOffset;
    this.previousScrollOffset = null;
    }
    }
    ...

    View Slide

  32. class ScrollingList extends Component {
    listRef = null;
    getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the scroll position so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
    return (
    this.listRef.scrollHeight - this.listRef.scrollTop
    );
    }
    return null;
    }
    componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we've just added new items.
    // Adjust scroll so these new items don't push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
    this.listRef.scrollTop =
    this.listRef.scrollHeight - snapshot;
    }
    }
    ...

    View Slide

  33. View Slide

  34. reactjs.org/blog/2018/03/27/update-on-async-rendering.html
    Further Reading

    View Slide

  35. migrating it.

    View Slide

  36. github.com/facebook/jscodeshift

    View Slide

  37. github.com/reactjs/react-codemod

    View Slide

  38. $ jscodeshift -t ./unsafe-mod.js ./src --parser=flow
    -t

    View Slide

  39. $ jscodeshift -t ./unsafe-mod.js ./src --parser=flow
    files or directory to transform
    -t

    View Slide

  40. $ jscodeshift -t ./unsafe-mod.js ./src --parser=flow
    files or directory to transform
    -t

    View Slide

  41. - "enzyme": "^3.3.0",
    - "enzyme-adapter-react-16": “^1.1.1”
    - "react-test-renderer": "^16.2.0",
    + "enzyme": "^3.6.0",
    + "enzyme-adapter-react-16": “^1.5.0",
    + "react-test-renderer": “^16.5.1",

    View Slide

  42. - wrapper.instance().componentWillMount();
    + wrapper.instance().UNSAFE_componentWillMount();

    View Slide

  43. Hooks

    View Slide

  44. View Slide

  45. https://reactjs.org/docs/
    hooks-intro.html

    View Slide

  46. Hooks
    import { useState } from 'react';
    function Example() {
    // Declare a new state variable, which we'll call "count"
    const [count, setCount] = useState(0);
    return (

    You clicked {count} times
    setCount(count + 1)}>
    Click me


    );
    }

    View Slide

  47. Looks like Recompose.
    Feels like Recompose.

    View Slide

  48. import { useState, useEffect } from 'react';
    function Example() {
    const [count, setCount] = useState(0);
    // Similar to componentDidMount and componentDidUpdate:
    useEffect(() => {
    // Update the document title using the browser API
    document.title = `You clicked ${count} times`;
    });
    return (

    You clicked {count} times
    setCount(count + 1)}>
    Click me


    );
    }

    View Slide

  49. class Example extends React.Component {
    constructor(props) {
    super(props);
    this.state = {
    count: 0
    };
    }
    componentDidMount() {
    document.title = `You clicked ${this.state.count} times`;
    }
    componentDidUpdate() {
    document.title = `You clicked ${this.state.count} times`;
    }
    render() {
    return (

    You clicked {this.state.count} times
    this.setState({ count: this.state.count + 1 })}>
    Click me


    );
    }
    }

    View Slide

  50. Cleanup

    View Slide

  51. class FriendStatus extends React.Component {
    constructor(props) {
    super(props);
    this.state = { isOnline: null };
    this.handleStatusChange = this.handleStatusChange.bind(this);
    }
    componentDidMount() {
    ChatAPI.subscribeToFriendStatus(
    this.props.friend.id,
    this.handleStatusChange
    );
    }
    componentWillUnmount() {
    ChatAPI.unsubscribeFromFriendStatus(
    this.props.friend.id,
    this.handleStatusChange
    );
    }
    handleStatusChange(status) {
    this.setState({
    isOnline: status.isOnline
    });
    }
    render() {

    View Slide

  52. import { useState, useEffect } from 'react';
    function FriendStatus(props) {
    const [isOnline, setIsOnline] = useState(null);
    function handleStatusChange(status) {
    setIsOnline(status.isOnline);
    }
    useEffect(() => {
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    // Specify how to clean up after this effect:
    return function cleanup() {
    ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
    };
    });
    if (isOnline === null) {
    return 'Loading...';
    }
    return isOnline ? 'Online' : 'Offline';
    }

    View Slide

  53. Cleanup

    View Slide

  54. // Create a Context
    const NumberContext = React.createContext();
    // It returns an object with 2 values:
    // { Provider, Consumer }
    const context = useContext(Context);

    View Slide

  55. Basic Hooks
    useState
    useEffect
    useContext
    Additional Hooks
    useReducer
    useCallback
    useMemo
    useRef
    useImperativeMethods
    useMutationEffect
    useLayoutEffect

    View Slide

  56. https://
    reactjs.org/blog/2018/03/29/
    react-v-16-3.html

    View Slide

  57. https://reactjs.org/docs/
    hooks-reference.html

    View Slide