-
Notifications
You must be signed in to change notification settings - Fork 27
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
document how to migrate from react #41
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,278 @@ | ||
# Migrating From React | ||
Choo borrows heavily from React. For many of us, it was the first experience we | ||
had with declarative rendering, and separation of events and data. | ||
|
||
However, there are a good amount of differences. At its core Choo is | ||
"declarative rendering" + "shared event emitter" + "router". Once you understand | ||
how these pieces fit together, you'll quickly be able to create an intuition for | ||
how Choo operates. | ||
|
||
## Creating New Projects | ||
React recommends using | ||
[create-react-app](https://github.com/facebookincubator/create-react-app) to | ||
create new project. Choo has a similar project called | ||
[create-choo-app](https://github.com/choojs/create-choo-app/). The output is | ||
different, but the process should feel familiar coming from React. | ||
|
||
## Declarative Rendering | ||
Both React and Choo have a system that allows you to define of "this is what the | ||
DOM should look like". React uses JSX, and Choo uses Template String Literals. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is a huge difference, and the main reason why I've never wanted to try React. Should we talk a bit more about the non-standard jsx? I mean how it forces you to use some specific environment config. Choo on the other side expect native DOM, we could even replace There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, although I don't think this guide should serve as a list of things that Choo has over React :P |
||
Let's take a look at how a "hello world" example compares: | ||
|
||
#### React | ||
```js | ||
var { ReactDOM } = require('react') | ||
|
||
var tree = (<h1>Hello, world!</h1>) | ||
ReactDOM.render(tree, document.body) | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var html = require('choo/html') | ||
|
||
var tree = html`<h1>Hello, world!</h1>` | ||
document.body.appendChild(tree) | ||
``` | ||
|
||
Quite similar, but not the same. | ||
|
||
### Attribute names | ||
HTML elements take all sorts of attributes. In React these attributes are named | ||
differently from the DOM (usually camel cased, but sometimes including other | ||
changes too). In Choo they have the same name as the DOM. | ||
|
||
Take for example the `class` attribute. In React this would be `className=`. In | ||
Choo it remains `class`. | ||
|
||
#### React | ||
```js | ||
var tree = ( | ||
<h1 className="foo bar"> | ||
Hello, world! | ||
</h1> | ||
) | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var tree = html` | ||
<h1 class="foo bar"> | ||
Hello, world! | ||
</h1> | ||
` | ||
``` | ||
|
||
### The Style Attribute | ||
A special attribute in React is the `style=` attribute. It takes an object | ||
containing style properties. In Choo we follow the DOM specification, and accept | ||
CSS directly. | ||
|
||
#### React | ||
```js | ||
var styles = { | ||
color: 'white', | ||
background: 'black' | ||
} | ||
var tree = ( | ||
<h1 style={styles}> | ||
Hello, world! | ||
</h1> | ||
) | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var styles = ` | ||
color: white; | ||
background: black; | ||
` | ||
var tree = html` | ||
<h1 style=${styles}> | ||
Hello, world! | ||
</h1> | ||
` | ||
``` | ||
|
||
### DOM Events | ||
React uses a wrapper around DOM events called ["synthetic | ||
events"](https://reactjs.org/docs/events.html). Choo exposes the DOM's events | ||
directly. The most notable difference here is that you can pass DOM events | ||
around asynchronously in Choo, while you can't do that in React. | ||
|
||
Binding events in Choo and React is quite similar, with a few syntactic | ||
differences. | ||
|
||
#### React | ||
```js | ||
var tree = ( | ||
<button onclick={onclick}> | ||
Click me! | ||
</button> | ||
) | ||
|
||
function onclick (e) { | ||
console.log('click!') | ||
} | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var tree = html` | ||
<button onclick={onclick}> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be |
||
Click me! | ||
</button> | ||
` | ||
|
||
function onclick (e) { | ||
console.log('click!') | ||
} | ||
``` | ||
|
||
## Classes | ||
React uses classes with lifecycles to componentize application code. We're in | ||
the process of introducing classes into Choo as well, because we like this | ||
pattern. You can follow along on the progress in | ||
[choojs/choo#593](https://github.com/choojs/choo/issues/593) and | ||
[choojs/choo#606](https://github.com/choojs/choo/pull/606). | ||
|
||
## Routing | ||
The most common router in React is probably `react-router`. It uses custom HTML | ||
tags to do the routing inline. | ||
|
||
### Base routing | ||
Let's create a basic routing example. We create two routes: `/`, and `/foo`. | ||
|
||
#### React | ||
```js | ||
var { BrowserRouter, Switch, Route } = require('react-router-dom') | ||
var render = require('react-dom').render | ||
var React = require('react') | ||
|
||
var tree = ( | ||
<BrowserRouter> | ||
<Switch> | ||
<Route exact path='/' component={mainView} /> | ||
<Route path='/foo' component={fooView} /> | ||
</Switch> | ||
</BrowserRouter> | ||
) | ||
render(tree, document.body) | ||
|
||
function mainView () { | ||
return ( | ||
<div> | ||
Woot, main view! | ||
</div> | ||
) | ||
} | ||
|
||
function fooView () { | ||
return ( | ||
<div> | ||
Woot, foo view! | ||
</div> | ||
) | ||
} | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var html = require('choo/html') | ||
var choo = require('choo') | ||
|
||
var app = choo() | ||
app.route('/', mainView) | ||
app.route('/foo', fooView) | ||
app.render('body') | ||
|
||
function mainView (state, emit) { | ||
return html` | ||
<body> | ||
Woot, main view! | ||
</body> | ||
` | ||
} | ||
|
||
function fooView (state, emit) { | ||
return html` | ||
<body> | ||
Woot, foo view! | ||
</body> | ||
` | ||
} | ||
``` | ||
|
||
### Hyperlinks | ||
Linking from one page to another is a common thing. In HTML we use `<a>` | ||
(anchor) tags for this purpose. With `react-router`, the recommended way is by | ||
using the `<Link>` tag. In Choo we detect whenever an `<a>` tag has been | ||
clicked, and handle routing inside our router. | ||
|
||
#### React | ||
```js | ||
var { BrowserRouter, Switch, Route } = require('react-router-dom') | ||
var render = require('react-dom').render | ||
var React = require('react') | ||
|
||
var tree = ( | ||
<BrowserRouter> | ||
<Switch> | ||
<Route exact path='/' component={mainView} /> | ||
<Route path='/foo' component={fooView} /> | ||
</Switch> | ||
</BrowserRouter> | ||
) | ||
render(tree, document.body) | ||
|
||
function mainView () { | ||
return ( | ||
<div> | ||
<Link to="/foo"> | ||
Click to go to foo. | ||
</Link> | ||
</div> | ||
) | ||
} | ||
|
||
function fooView () { | ||
return ( | ||
<div> | ||
<Link to="/"> | ||
Click to go back home. | ||
</Link> | ||
</div> | ||
) | ||
} | ||
``` | ||
|
||
#### Choo | ||
```js | ||
var html = require('choo/html') | ||
var choo = require('choo') | ||
|
||
var app = choo() | ||
app.route('/', mainView) | ||
app.route('/foo', fooView) | ||
app.render('body') | ||
|
||
function mainView (state, emit) { | ||
return html` | ||
<body> | ||
<a href="/foo"> | ||
Click to go to foo. | ||
</a> | ||
</body> | ||
` | ||
} | ||
|
||
function fooView (state, emit) { | ||
return html` | ||
<body> | ||
<a href="/"> | ||
Click to go to back home. | ||
</a> | ||
</body> | ||
` | ||
} | ||
``` | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An outro or a summary would be nice! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"create an intuition for" -> "understand"