React components

From wikinotes
Revision as of 20:59, 10 December 2022 by Will (talk | contribs) (→‎DOM Events)

Documentation

component docs https://reactjs.org/docs/react-component.html
fragment docs https://reactjs.org/docs/fragments.html
list docs
portal docs https://reactjs.org/docs/portals.html

Components

Component Functions

function Description() {
    return (
        <h1>Description</h1>
        <p>{this.props.paragraph}</p>
    )
}
<Description paragraph="a very long..." />

Component Classes

class Employee extends React.Component {
  constructor(props) {
    super(props);
    this.state = {name: props.name, id: props.id}
  }

  render() {
    return (
      <div>
        <h1>Name: {this.state.name}</h1>
        <h2>ID: {this.state.id}</h2>
      </div>
    );
  }
}
<Employee name="vaderd" id="101" />

Attributes

this.props

Parameters are passed parameters using xml tag attributes.
Within the component, they are axposed as attributes on the this.props variable.

ReactDOM.render(
    <Description name="Alex" />,         // <-- use component
    document.getElementById('root')
);
function Description() {
    return <p>hello, {this.props.name}</p>;  // <-- access props in component
}

this.state

this.state is a special object property to store UI related info.
The component will be re-rendered every time the this.setState() is called.

class Thing extends React.Component {
    constructor(props) {
        super(props);
        this.state = { collapsed: false };
    }

    render() {
        if (this.state.collapsed) {
            <p>collapsed</p>
        } else {
            <p>expanded</p>
        }
    }
}
this.setState({ collapsed: false }) // good: update state
this.state = { collapsed: false }   // bad:

Render Types

Elements

Generally, React requires that a single top-level html-element is returned by each component.

function Person extends React.Component {
    render() {
        return (
            <table>
                <tr><th>...</th></tr>
                <tr><th>...</th></tr>
            </table>
        );
    }
}

Lists

You may render() a list of elements to some compound types, like lists.
Each item requires a unique key so react can keep track of CRUD operations with list items.

function ListItems extends React.Component {
    render() {
        return [{key: "a", text: "aaa"},
                {key: "b", text: "bbb"},
                {key: "c", text: "ccc"}].map((x) => <li key={x.key}> {x.text} </li> );
    }
}

function MyList extends React.Component {
    render() {
        return (
            <ul>
            <ListItems />
            </ul>
    }
}

Fragments

Fragments are a special wrapper type that allows you to return multiple top-level html-elements in one clump.
They do not need to be a homogenous collection of top-level elements.

You can use either of the following tags:

  • <React.Fragment>...</React.Fragment>
  • <>...</>
<table>
  <tr>
    <Columns />  // <-- fragment with several items
  </tr>
</table>
import React from 'react';

function Columns(props) {
    return (
        <React.Fragment>
          <td>foo</td>
          <td>bar</td>
          <td>baz</td>
        </React.Fragment>
    );
}

Lifecycle Methods

React components have methods to mount/unmount behaviours when the object is first created or destroyed.
These can set/unset timers to auto-update the object.
These behave similarly to constructor/destructor as hooks, except their events correspond with adding/removing them from the DOM.

Check out the tutorial (might need to scroll to methods).

class Foo extends React.Component {
  componentDidMount() { ... }      // runs after first 'render()'
  componentWillUnmount() { ... }   // runs if object is removed from the DOM
}

DOM Events

You can subscribe to DOM events with callbacks similarly to javascript.
except that events are in camelcase
and callbacks are defined as methods rather than strings.

React DOM events are abstracted, so they behave the same on all browsers. See SyntheticEvent docs.

See https://reactjs.org/docs/handling-events.html

class HelloWorld extends React.Component {
  sayHello() {
    console.log('hello')
  }

  render() {
    return (
      <button onClick={() => this.sayHello()}> // anonymous callback variation
        Say Hello
      </button>

      <button onClick{sayHello}>               // instance-method callback variation
        Say Hello
      </button>
    );
  }
}