Skip to content

Commit

Permalink
Move docs to docs folder
Browse files Browse the repository at this point in the history
  • Loading branch information
ahangarha committed Sep 24, 2023
1 parent 7e369d6 commit ab98b52
Show file tree
Hide file tree
Showing 10 changed files with 891 additions and 854 deletions.
864 changes: 10 additions & 854 deletions README.md

Large diffs are not rendered by default.

47 changes: 47 additions & 0 deletions docs/common-errors.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Common Errors

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Getting warning for `Can't resolve 'react-dom/client'` in React < 18](#getting-warning-for-cant-resolve-react-domclient-in-react--18)
- [Undefined Set](#undefined-set)
- [Using TheRubyRacer](#using-therubyracer)
- [HMR](#hmr)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

## Getting warning for `Can't resolve 'react-dom/client'` in React < 18

You may see a warning like this when building a Webpack bundle using any version of React below 18. This warning can be safely [suppressed](https://webpack.js.org/configuration/other-options/#ignorewarnings) in your Webpack configuration. The following is an example of this suppression in `config/webpack/webpack.config.js`:

```diff
- const { webpackConfig } = require('shakapacker')
+ const { webpackConfig, merge } = require('shakapacker')

+const ignoreWarningsConfig = {
+ ignoreWarnings: [/Module not found: Error: Can't resolve 'react-dom\/client'/],
+};

- module.exports = webpackConfig
+ module.exports = merge({}, webpackConfig, ignoreWarningsConfig)
```

## Undefined Set
```
ExecJS::ProgramError (identifier 'Set' undefined):
(execjs):1
```
If you see any variation of this issue, see [Using TheRubyRacer](#using-therubyracer)


## Using TheRubyRacer
TheRubyRacer [hasn't updated LibV8](https://github.com/cowboyd/therubyracer/blob/master/therubyracer.gemspec#L20) (The library that powers Node.js) from v3 in 2 years, any new features are unlikely to work.

LibV8 itself is already [beyond version 7](https://github.com/cowboyd/libv8/releases/tag/v7.3.492.27.1) therefore many serverside issues are caused by old JS engines and fixed by using an up to date one such as [MiniRacer](https://github.com/discourse/mini_racer) or [TheRubyRhino](https://github.com/cowboyd/therubyrhino) on JRuby.

## HMR

Check out [Enabling Hot Module Replacement (HMR)](https://github.com/shakacode/shakapacker/blob/master/docs/react.md#enabling-hot-module-replacement-hmr) in Shakapacker documentation.

One caveat is that currently you [cannot Server-Side Render along with HMR](https://github.com/reactjs/react-rails/issues/925#issuecomment-415469572).
138 changes: 138 additions & 0 deletions docs/component-generator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Component Generator

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->

- [Use with JBuilder](#use-with-jbuilder)
- [Camelize Props](#camelize-props)
- [Changing Component Templates](#changing-component-templates)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->


You can generate a new component file with:

```sh
rails g react:component ComponentName prop1:type prop2:type ... [options]
```

For example,

```sh
rails g react:component Post title:string published:bool published_by:instanceOf{Person}
```

would generate:

```JSX
var Post = createReactClass({
propTypes: {
title: PropTypes.string,
published: PropTypes.bool,
publishedBy: PropTypes.instanceOf(Person)
},

render: function() {
return (
<React.Fragment>
Title: {this.props.title}
Published: {this.props.published}
Published By: {this.props.publishedBy}
</React.Fragment>
);
}
});
```

The generator also accepts options:

- `--es6`: generates a function component
- `--coffee`: use CoffeeScript

For example,

```sh
rails g react:component ButtonComponent title:string --es6
```

would generate:

```jsx
import React from "react"
import PropTypes from "prop-types"

function ButtonComponent(props) {
return (
<React.Fragment>
Title: {this.props.title}
</React.Fragment>
);
}

ButtonComponent.propTypes = {
title: PropTypes.string
};

export default ButtonComponent
```

**Note:** In a Shakapacker project, es6 template is the default template in the generator.

Accepted PropTypes are:

- Plain types: `any`, `array`, `bool`, `element`, `func`, `number`, `object`, `node`, `shape`, `string`
- `instanceOf` takes an optional class name in the form of `instanceOf{className}`.
- `oneOf` behaves like an enum, and takes an optional list of strings in the form of `'name:oneOf{one,two,three}'`.
- `oneOfType` takes an optional list of react and custom types in the form of `'model:oneOfType{string,number,OtherType}'`.

Note that the arguments for `oneOf` and `oneOfType` must be enclosed in single quotes
to prevent your terminal from expanding them into an argument list.

## Use with JBuilder

If you use Jbuilder to pass a JSON string to `react_component`, make sure your JSON is a stringified hash,
not an array. This is not the Rails default -- you should add the root node yourself. For example:

```ruby
# BAD: returns a stringified array
json.array!(@messages) do |message|
json.extract! message, :id, :name
json.url message_url(message, format: :json)
end

# GOOD: returns a stringified hash
json.messages(@messages) do |message|
json.extract! message, :id, :name
json.url message_url(message, format: :json)
end
```

## Camelize Props

You can configure `camelize_props` option:

```ruby
MyApp::Application.configure do
config.react.camelize_props = true # default false
end
```

Now, Ruby hashes given to `react_component(...)` as props will have their keys transformed from _underscore_- to _camel_-case, for example:

```ruby
{ all_todos: @todos, current_status: @status }
# becomes:
{ "allTodos" => @todos, "currentStatus" => @status }
```

You can also specify this option in `react_component`:

```erb
<%= react_component('HelloMessage', {name: 'John'}, {camelize_props: true}) %>
```

## Changing Component Templates

To make simple changes to Component templates, copy the respective template file to your Rails project at `lib/templates/react/component/template_filename`.

For example, to change the [ES6 Component template](https://github.com/reactjs/react-rails/blob/master/lib/generators/templates/component.es6.jsx), copy it to `lib/templates/react/component/component.es6.jsx` and modify it.
16 changes: 16 additions & 0 deletions docs/controller-actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Controller Actions

Components can also be server-rendered directly from a controller action with the custom `component` renderer. For example:

```ruby
class TodoController < ApplicationController
def index
@todos = Todo.all
render component: 'TodoList', props: { todos: @todos }, tag: 'span', class: 'todo'
end
end
```

You can also provide the "usual" `render` arguments: `content_type`, `layout`, `location` and `status`. By default, your current layout will be used and the component, rather than a view, will be rendered in place of `yield`. Custom data-* attributes can be passed like `data: {remote: true}`.

Prerendering is set to `true` by default, but can be turned off with `prerender: false`.
Loading

0 comments on commit ab98b52

Please sign in to comment.