#+TITLE: React layer

#+TAGS: framework|layer|programming

[[file:img/react.png]]

* Table of Contents                     :TOC_5_gh:noexport:
- [[#description][Description]]
  - [[#features][Features:]]
- [[#install][Install]]
- [[#optional-configuration][Optional Configuration]]
- [[#key-bindings][Key bindings]]
  - [[#rjsx-mode][rjsx-mode]]
  - [[#formatting-web-beautify][Formatting (web-beautify)]]
    - [[#documentation-js-doc][Documentation (js-doc)]]
  - [[#documentation-tern][Documentation (tern)]]

* Description
ES6 and JSX ready configuration layer for React
It will automatically recognize =.jsx= files and files with =react= imported.

** Features:
- on-the-fly syntax checking
- proper syntax highlight and indentation with jsx
- backend support for autocompletion as in rjsx-mode
- jsfmt automatic formatting
- js2-refactor
- js-doc

* Install
To use this configuration layer, add it to your =~/.spacemacs=. You will need to
add =react= to the existing =dotspacemacs-configuration-layers= list in this
file.

React layer uses the same backend defined in javascript layer. Options are =tern= and =lsp=.

React layer also uses the same import backend defined in javascript layer.

To use the on-the-fly syntax checking, install =eslint= with babel and react
support:

#+BEGIN_SRC sh
  $ npm install -g eslint babel-eslint eslint-plugin-react
#+END_SRC

If your project do not use a custom =.eslintrc= file I strongly advice you to
try out this one by Airbnb:
[[https://github.com/airbnb/javascript/blob/master/linters/.eslintrc][.eslintrc]]

When =lsp= is set as the backend, but you don't want to use lsp as the linter,
set the variable =javascript-lsp-linter= to =nil= in the Javascript layer.

React layer uses the same formatter defined in javascript layer. Options are
=web-beautify= and =prettier=.
To use automatic code formatting you need to install ~js-beautify~ or ~prettier~
with:

#+BEGIN_SRC sh
  $ npm install -g js-beautify prettier
#+END_SRC

If you install these in non-standard locations, then add the following to your
=dotspacemacs/user-init= function:

#+BEGIN_SRC elisp
  (add-to-list 'exec-path "/path/to/node/bins" t)
#+END_SRC

Be sure to have the ~e4x~ option set to ~true~ on your ~.jsbeautifyrc~ here it
is my configuration as an example:

#+BEGIN_SRC json
  {
    "indent_size": 2,
    "indent_char": " ",
    "eol": "\n",
    "indent_level": 0,
    "indent_with_tabs": false,
    "preserve_newlines": true,
    "max_preserve_newlines": 2,
    "jslint_happy": false,
    "space_after_anon_function": false,
    "brace_style": "collapse",
    "keep_array_indentation": false,
    "keep_function_indentation": false,
    "space_before_conditional": true,
    "break_chained_methods": true,
    "eval_code": false,
    "unescape_strings": false,
    "wrap_line_length": 80,
    "wrap_attributes": "auto",
    "wrap_attributes_indent_size": 2,
    "e4x": true,
    "end_with_newline": true,
    "brace_style": "collapse-preserve-inline"
  }
#+END_SRC

* Optional Configuration
You may refer to the =web-mode= configuration for fine tuning the indenting
behaviour.

For example to have a consistent 2 spaces indenting both on =js= and =jsx= you
may use these settings:

#+BEGIN_SRC emacs-lisp
  (setq-default
   ;; js2-mode
   js2-basic-offset 2
   ;; web-mode
   css-indent-offset 2
   web-mode-markup-indent-offset 2
   web-mode-css-indent-offset 2
   web-mode-code-indent-offset 2
   web-mode-attr-indent-offset 2)
#+END_SRC

And if you want to have 2 space indent also for element's attributes,
concatenations and contiguous function calls:

#+BEGIN_SRC emacs-lisp
  (with-eval-after-load 'web-mode
    (add-to-list 'web-mode-indentation-params '("lineup-args" . nil))
    (add-to-list 'web-mode-indentation-params '("lineup-concats" . nil))
    (add-to-list 'web-mode-indentation-params '("lineup-calls" . nil)))
#+END_SRC

* Key bindings
** rjsx-mode
The =javascript= layers keymap is set as the parent of the =react= layers keymap.
Check the [[https://github.com/syl20bnr/spacemacs/blob/develop/layers/+lang/javascript/README.org#key-bindings][javascript layers documentation]] for additional key bindings.

| Key binding   | Description                                                                      |
|---------------+----------------------------------------------------------------------------------|
| ~<~           | inserts </> whenever it would start a new JSX node                               |
| ~>~           | right before the slash in a self-closing tag automatically inserts a closing tag |
| ~SPC m r l t~ | log thing at point                                                               |
| ~SPC m r r t~ | rename tag at point                                                              |

** Formatting (web-beautify)

| Key binding | Description                                                  |
|-------------+--------------------------------------------------------------|
| ~SPC m =~   | beautify code in js2-mode, json-mode, web-mode, and css-mode |

*** Documentation (js-doc)
You can check more [[https://github.com/mooz/js-doc/][here]]

| Key binding   | Description                           |
|---------------+---------------------------------------|
| ~SPC m r d b~ | insert JSDoc comment for current file |
| ~SPC m r d f~ | insert JSDoc comment for function     |
| ~SPC m r d t~ | insert tag to comment                 |
| ~SPC m r d h~ | show list of available jsdoc tags     |

** Documentation (tern)

| Key binding   | Description                                                                              |
|---------------+------------------------------------------------------------------------------------------|
| ~SPC m C-g~   | brings you back to last place you were when you pressed M-..                             |
| ~SPC m g g~   | jump to the definition of the thing under the cursor                                     |
| ~SPC m g G~   | jump to definition for the given name                                                    |
| ~SPC m h d~   | find docs of the thing under the cursor. Press again to open the associated URL (if any) |
| ~SPC m h t~   | find the type of the thing under the cursor                                              |
| ~SPC m r r V~ | rename variable under the cursor using tern                                              |
