Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move docs to docs folder #1312

Merged
merged 5 commits into from
Oct 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
892 changes: 38 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.
22 changes: 22 additions & 0 deletions docs/controller-actions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Controller Actions

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

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


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