React.js

TypeScript

  • New project

    • yarn create react-app my-app --template typescript
  • Existing project

    • npm i -S typescript @types/node @types/react @types/react-dom @types/jest

    • Rename JS source code file to be a TypeScript file (e.g. src/index.js to src/index.tsx) and restart your development server!

  • Resources

API

setState

PureComponent

  • PureComponent only checkes reassignment of state variables. In the case of an array, mutation of the array content cannot be detected.

    • The simplest way to avoid this problem is to avoid mutating values that you are using as props or state.

      // state variable is an array
      this.setState(state => ({
        words: state.words.concat(["marklar"]); // Or words: [...state.words, 'marklar']
      }));
      // state variable is an object
      this.setState(state => ({
        colormap: Object.assign({}, state, { right: "blue" });
      }));
    • When using TypeScript, use readonly to ensure object immutability. Create a new object with updated values and replace the old object to achieve modification.

JSX

Optional attributes of components

Using spread opeartor to add optional attributes:

    public render() {
        const {menuPlacement, menuPosition} = this.props;
        const opts: Partial<Props<IOption>> = {};
        if (this.props.parentRef != null) {
            opts.menuPortalTarget = this.props.parentRef.current;
        }
        return (
            <Select options={LabelAutocomplete.generateOptions(this.props.labels)}
                    backspaceRemovesValue={false}
                    closeMenuOnSelect={false}
                    value={this.state.value}
                    onChange={this.onChange}
                    inputValue={this.state.inputValue}
                    isSearchable={true}
                    onInputChange={this.onInputChange}
                    placeholder="Select labels"
                    minMenuHeight={100}
                    maxMenuHeight={150}
                    menuIsOpen={this.state.isMenuOpen}
                    menuPlacement={menuPlacement}
                    menuPortalTarget={document.body}
                    menuPosition={menuPosition}
                    onMenuOpen={this.onMenuOpen}
                    onMenuClose={this.onMenuClose}
                    styles={selectStyles}
                    isMulti={true}
                    {...opts} />
        );
    }

Default properties of components

Support for defaultProps in JSX (opens in a new tab)

Pass value from child to parent component

  1. Define an arrow function in parent to change state
  2. Pass the function reference to child as a prop
  3. Invoke the function in child via an event handler and pass the value as argument
// Parent
class ParentComponent extends React.Component {
  state: { language: "" };
 
  handleLanguage = (langValue) => {
    this.setState({ language: langValue });
  };
 
  render() {
    return (
      <div className="col-sm-9">
        <SelectLanguage onSelectLanguage={this.handleLanguage} />
      </div>
    );
  }
}
// Child
var json = require("json!../languages.json");
var jsonArray = json.languages;
 
export class SelectLanguage extends React.Component {
  state = {
    selectedCode: "",
    selectedLanguage: jsonArray[0],
  };
 
  handleLangChange = () => {
    var lang = this.dropdown.value;
    this.props.onSelectLanguage(lang);
  };
 
  render() {
    return (
      <div>
        <DropdownList
          ref={(ref) => (this.dropdown = ref)}
          data={jsonArray}
          valueField="lang"
          textField="lang"
          caseSensitive={false}
          minLength={3}
          filter="contains"
          onChange={this.handleLangChange}
        />
      </div>
    );
  }
}

Use && for concise conditional rendering

  render() {
    // change code below this line
    return (
       <div>
         <button onClick={this.toggleDisplay}>Toggle Display</button>
         {this.state.display && <h1>Displayed!</h1>}
       </div>
    );
  }

Redux

  • Application state should be stored in a single immutable object.

Code Organization with ES6 Modules

src/
  index.js
  index.css
  constants/
    index.js
  components/
    App/
      index.js
      test.js
      index.css
    Button/
      index.js
      test.js
      index.css
  • When you use the index.js naming convention, you can omit the filename from the relative path.
  • The index.js file is the entry point to a module. It describes the public API to the module. External modules are only allowed to use the index.js file to import shared code from the module.