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. • Official Context API • createRef API • forwardRef API

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

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

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

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

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

    • Component Lifecycle Changes • Strict Mode • React Hooks What’s New?
  7. New context API const ThemeContext = React.createContext('light'); class ThemeProvider extends

    React.Component { state = {theme: 'light'}; render() { return ( <ThemeContext.Provider value={this.state.theme}> {this.props.children} </ThemeContext.Provider> ); } }
  8. New context API class ThemedButton extends React.Component { render() {

    return ( <ThemeContext.Consumer> {theme => <Button theme={theme} />} </ThemeContext.Consumer> ); } }
  9. createRef class InputComponent extends Component { constructor(props) { super(props); this.inputRef

    = React.createRef(); } componentDidMount() { this.inputRef.current.focus(); } render() { return <input type="text" ref={this.inputRef} />; } }
  10. 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.
  11. const FancyButton = React.forwardRef((props, ref) => ( <button ref={ref} className="FancyButton">

    {props.children} </button> )); // You can now get a ref directly to the DOM button: const ref = React.createRef(); <FancyButton ref={ref}>Click me!</FancyButton>; fowardRef
  12. import React from 'react'; function Application() { return ( <div>

    <Header /> <React.StrictMode> <div> <ComponentOne /> <ComponentTwo /> </div> </React.StrictMode> <Footer /> </div> ); } 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.
  13. • 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
  14. 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, }); } } }
  15. // 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; } }
  16. // 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; } } ...
  17. 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; } } ...
  18. - "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",
  19. Hooks import { useState } from 'react'; function Example() {

    // Declare a new state variable, which we'll call "count" const [count, setCount] = useState(0); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
  20. 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 ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); }
  21. 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 ( <div> <p>You clicked {this.state.count} times</p> <button onClick={() => this.setState({ count: this.state.count + 1 })}> Click me </button> </div> ); } }
  22. 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() {
  23. 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'; }
  24. // Create a Context const NumberContext = React.createContext(); // It

    returns an object with 2 values: // { Provider, Consumer } const context = useContext(Context);
  25. Basic Hooks useState useEffect useContext Additional Hooks useReducer useCallback useMemo

    useRef useImperativeMethods useMutationEffect useLayoutEffect