Skip to content

Latest commit

 

History

History
620 lines (453 loc) · 12.1 KB

File metadata and controls

620 lines (453 loc) · 12.1 KB

basic types

{{ ::cards-header:: }}

Components

import React from 'react'
import ReactDOM from 'react-dom'
class Hello extends React.Component {
  render () {
    return <div className='message-box'>
      Hello {this.props.name}
    </div>
  }
}
const el = document.body
ReactDOM.render(<Hello name='John' />, el)

Use the React.js jsfiddle to start use (or the unofficial jsbin)

{{ ::card-item:: }}

Properties

<Video fullscreen={true} />
render () {
  this.props.fullscreen
  ···
}

Use this.props to access properties passed to the component.

See: Properties

{{ ::card-item:: }}

States

this.setState({ username: 'rstacruz' })
render () {
  this.state.username
  ···
}

Use states (this.state) to manage dynamic data.

See: States

{{ ::card-item:: }}

Nesting

class Info extends React.Component {
  render () {
    const { avatar, username } = this.props

    return <div>
      <UserAvatar src={avatar} />
      <UserProfile username={username} />
    </div>
  }
}

Nest components to separate concerns.

See: Composing Components

{{ ::card-item:: }}

Children

<AlertBox>
  <h1>You have pending notifications</h1>
</AlertBox>
class AlertBox extends React.Component {
  render () {
    return <div className='alert-box'>
      {this.props.children}
    </div>
  }
}

Children are passed as the children property.

{{ ::group:: }}

Defaults

{{ ::cards-header:: }}

Setting default props

Hello.defaultProps = {
  color: 'blue'
}

See: defaultProps

{{ ::card-item:: }}

Setting default state

class Hello extends React.Component {
  constructor (props) {
    super(props)
    this.state = { visible: true }
  }
}

Set the default state in the constructor().

See: Setting the default state

{{ ::group:: }}

Other components

{{ ::cards-header:: }}

Function components

function MyComponent ({ name }) {
  return <div className='message-box'>
    Hello {name}
  </div>
}

Functional components have no state. Also, their props are passed as the first parameter to a function.

See: Function and Class Components

{{ ::card-item:: }}

Pure components

class MessageBox extends React.PureComponent {
  ···
}

Performance-optimized version of React.Component. Doesn't rerender if props/state hasn't changed.

See: Pure components

{{ ::card-item:: }}

Component API

this.forceUpdate()
this.setState({ ... })
this.state
this.props

These methods and properties are available for Component instances.

See: Component API

{{ ::group:: }}

Lifecycle

{{ ::cards-header:: }}

Mounting

Method Description
constructor (props) Before rendering #
componentWillMount() Don't use this #
render() Render #
componentDidMount() After rendering (DOM available) #
--- ---
componentWillUnmount() Before DOM removal #
--- ---
componentDidCatch() Catch errors (16+) #

Set initial the state on constructor(). Add DOM event handlers, timers (etc) on componentDidMount(), then remove them on componentWillUnmount().

{{ ::card-item:: }}

Updating

Method Description
componentWillReceiveProps (newProps) Use setState() here
shouldComponentUpdate (newProps, newState) Skips render() if returns false
componentWillUpdate (newProps, newState) Can't use setState() here
render() Render
componentDidUpdate (prevProps, prevState) Operate on the DOM here

Called when parents change properties and .setState(). These are not called for initial renders.

See: Component specs

{{ ::group:: }}

DOM nodes

{{ ::cards-header:: }}

References

class MyComponent extends React.Component {
  render () {
    return <div>
      <input ref={el => this.input = el} />
    </div>
  }

  componentDidMount () {
    this.input.focus()
  }
}

Allows access to DOM nodes.

See: Refs and the DOM

{{ ::card-item:: }}

DOM Events

class MyComponent extends React.Component {
  render () {
    <input type="text"
        value={this.state.value}
        onChange={event => this.onChange(event)} />
  }

  onChange (event) {
    this.setState({ value: event.target.value })
  }
}

Pass functions to attributes like onChange.

See: Events

{{ ::group:: }}

Other features

{{ ::cards-header:: }}

Transferring props

<VideoPlayer src="video.mp4" />
class VideoPlayer extends React.Component {
  render () {
    return <VideoEmbed {...this.props} />
  }
}

Propagates src="..." down to the sub-component.

See Transferring props

{{ ::card-item:: }}

Top-level API

React.createClass({ ... })
React.isValidElement(c)
ReactDOM.render(<Component />, domnode, [callback])
ReactDOM.unmountComponentAtNode(domnode)
ReactDOMServer.renderToString(<Component />)
ReactDOMServer.renderToStaticMarkup(<Component />)

There are more, but these are most common.

See: React top-level API

{{ ::group:: }}

JSX patterns

{{ ::cards-header:: }}

Style shorthand

var style = { height: 10 }
return <div style={style}></div>
return <div style={{ margin: 0, padding: 0 }}></div>

See: Inline styles

{{ ::card-item:: }}

Inner HTML

function markdownify() { return "<p>...</p>"; }
<div dangerouslySetInnerHTML={{__html: markdownify()}} />

See: Dangerously set innerHTML

{{ ::card-item:: }}

Lists

class TodoList extends React.Component {
  render () {
    const { items } = this.props

    return <ul>
      {items.map(item =>
        <TodoItem item={item} key={item.key} />)}
    </ul>
  }
}

Always supply a key property.

{{ ::card-item:: }}

Conditionals

<div>
  {showMyComponent
    ? <MyComponent />
    : <OtherComponent />}
</div>

{{ ::card-item:: }}

Short-circuit evaluation

<div>
  {showPopup && <Popup />}
</div>

{{ ::group:: }}

New features

{{ ::cards-header:: }}

Returning fragments

render () {
  // Don't forget the keys!
  return [
    <li key="A">First item</li>,
    <li key="B">Second item</li>
  ]
}

You can return multiple nodes as arrays.

See: Fragments and strings

{{ ::card-item:: }}

Returning strings

render() {
  return 'Look ma, no spans!';
}

You can return just a string.

See: Fragments and strings

{{ ::card-item:: }}

Errors

class MyComponent extends React.Component {
  ···
  componentDidCatch (error, info) {
    this.setState({ error })
  }
}

Catch errors via componentDidCatch. (React 16+)

See: Error handling in React 16

{{ ::card-item:: }}

Portals

render () {
  return React.createPortal(
    this.props.children,
    document.getElementById('menu')
  )
}

This renders this.props.children into any location in the DOM.

See: Portals

{{ ::card-item:: }}

Hydration

const el = document.getElementById('app')
ReactDOM.hydrate(<App />, el)

Use ReactDOM.hydrate instead of using ReactDOM.render if you're rendering over the output of ReactDOMServer.

See: Hydrate

{{ ::group:: }}

Property validation

{{ ::cards-header:: }}

PropTypes

import PropTypes from 'prop-types'

See: Typechecking with PropTypes

Basic

type Description
any Anything
string String
number Number
func Function
bool True or false

Enum

type Description
oneOf(any) Enum types
oneOfType(type array) Union

Array

type Description
array Array
arrayOf(...) ---

Object

type Description
object
objectOf(...) Object with values of a certain type
instanceOf(...) Instance of a class
shape(...)

Elements

type Description
element React element
node DOM node

Required

type Description
(···).isRequired Required

{{ ::card-item:: }}

Basic types

MyComponent.propTypes = {
  email:      PropTypes.string,
  seats:      PropTypes.number,
  callback:   PropTypes.func,
  isClosed:   PropTypes.bool,
  any:        PropTypes.any
}

{{ ::card-item:: }}

Required types

MyCo.propTypes = {
  name:  PropTypes.string.isRequired
}

{{ ::card-item:: }}

Elements

MyCo.propTypes = {
  // React element
  element: PropTypes.element,

  // num, string, element, or an array of those
  node: PropTypes.node
}

{{ ::card-item:: }}

Enumerables (oneOf)

MyCo.propTypes = {
  direction: PropTypes.oneOf([
    'left', 'right'
  ])
}

{{ ::card-item:: }}

Arrays and objects

MyCo.propTypes = {
  list: PropTypes.array,
  ages: PropTypes.arrayOf(PropTypes.number),
  user: PropTypes.object,
  user: PropTypes.objectOf(PropTypes.number),
  message: PropTypes.instanceOf(Message)
}
MyCo.propTypes = {
  user: PropTypes.shape({
    name: PropTypes.string,
    age:  PropTypes.number
  })
}

Use .array[Of], .object[Of], .instanceOf, .shape.

{{ ::card-item:: }}

Custom validation

MyCo.propTypes = {
  customProp: (props, key, componentName) => {
    if (!/matchme/.test(props[key])) {
      return new Error('Validation failed!')
    }
  }
}

{{ ::group:: }}

Also see

{{ ::cards-header:: }}