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

the new react

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

the new react

Avatar for Raphael Amorim

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