News in React 16

Tomáš Trepka

What, when?

  • 16.0.0 - September 26, 2017
  • 16.2.0 - November 28, 2017
  • 16.3.0 - March 29, 2018
  • 16.3.2 - April 16, 2018

 

  1. Error boundaries (16.0.0)
  2. Fragments (16.2.0)
  3. Context API (16.3.0)
  4. Lifecycle methods (16.3.0)
  5. Refs (16.3.0)

1. Error boundaries

  • Part of UI shouldn't break whole app
  • JSX "try/catch"
  • class with componentDidCatch
  • wrap components

2. Fragments

  • List of children
  • Wrap in <div>
  • 16.0.0 - array
  • <React.Fragment>
  • <> shorthand
render() {
  return (
    <>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </>
  );
}
render() {
  return (
    <div>
      Some text.
      <h2>A heading</h2>
      More text.
      <h2>Another heading</h2>
      Even more text.
    </div>
  );
}
render() {
  return [
    'Some text',
    <h2 key="someKey">A heading</h2>,
    'More text.',
    <h2 key="anotherKey">Another heading</h2>,
    'Even more text.',
  ];
}

3. Context API

  • Used for global data - theme, language, user...
  • Was experimental, Redux, completely rewritten
  • Don't overuse just cause you're lazy!
// App.js
export const ThemeContext = React.createContext('light');

<ThemeContext.Provider value="dark">
  <Toolbar />
</ThemeContext.Provider>
// Toolbar.js
<div>
  <ThemedButton />
</div>
// ThemedButton.js
<ThemeContext.Consumer>
  {theme => <Button {...props} theme={theme} />}
</ThemeContext.Consumer>

4. Lifecycle methods

  • deprecated

 

  • new methods
static getDerivedStateFromProps(nextProps, prevState)
 getSnapshotBeforeUpdate(prevProps, prevState)
  • after instantiation, when receiving props
  • return new state object or null
  • before mutations to DOM are made
  • return value passed to
componentWillMount
componentWillReceiveProps
componentWillUpdate
componentDidUpdate

Update state based on props

class ExampleComponent extends React.Component {
  state = {
    color: colors[this.props.palette][0]
  };

  componentWillReceiveProps(nextProps) {
    if (this.props.palette !== nextProps.palette) {
      this.setState({ color: colors[nextProps.palette][0] });
    }
  }
}
class ExampleComponent extends React.Component {
  state = {
    color: colors[this.props.palette][0],
    lastPalette: null,
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.palette !== prevState.lastPalette) {
      return {
        color: colors[nextProps.palette][0],
        lastPalette: nextProps.palette,
      };
    }
    return null;
}

Side effects on props change

class ConnectionsScreen extends React.Component {
  componentDidUpdate(prevProps, prevState) {
    if (this.props.currency !== prevProps.currency) {
      this.getConnections();
    }
  }
}
class ConnectionsScreen extends React.Component {
  componentWillReceiveProps(nextProps) {
    if (nextProps.currency !== this.props.currency) {
      this.getConnections();
    }
  }
}

5. Refs

  • new way of writing
  • ref forwarding
  • get instance of component or DOM element, focus, scroll...
<input ref="inputRef" />
this.setInputRef = element => {
  this.inputRef = element;
};
...
<input ref={this.setInputRef} />
this.inputRef = React.createRef();
...

<input ref={this.inputRef} />

Ref forwarding

  • pass ref to inner component
const FancyButton = props => (
  <button ref={props.ref} className="FancyButton">
    {props.children}
  </button>
);

const ref = React.createRef();
<FancyButton ref={ref}>
  Click me!
</FancyButton>;
const FancyButton = React.forwardRef((props, ref) => (
  <button ref={ref} className="FancyButton">
    {props.children}
  </button>
));

const ref = React.createRef();
<FancyButton ref={ref}>
  Click me!
</FancyButton>;

Thank you!

Questions?

News in React 16

By Tomáš Trepka

News in React 16

  • 255