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

Update the homepage with ES6 #7868

Merged
merged 2 commits into from
Oct 4, 2016
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ React is a JavaScript library for building user interfaces.
We have several examples [on the website](https://facebook.github.io/react/). Here is the first one to get you started:

```js
var HelloMessage = React.createClass({
render: function() {
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
});
}

ReactDOM.render(
<HelloMessage name="John" />,
Expand Down
4 changes: 2 additions & 2 deletions docs/Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ require('open-uri')
desc "download babel-browser"
task :fetch_remotes do
IO.copy_stream(
open('https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.34/browser.min.js'),
'js/babel-browser.min.js'
open('https://unpkg.com/babel-[email protected]/babel.min.js'),
'js/babel.min.js'
)
end

Expand Down
11 changes: 6 additions & 5 deletions docs/_js/examples/hello.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
var name = Math.random() > 0.5 ? 'Jane' : 'John';
var HELLO_COMPONENT = `
var HelloMessage = React.createClass({
render: function() {
class HelloMessage extends React.Component {
render() {
return <div>Hello {this.props.name}</div>;
}
});
}

ReactDOM.render(<HelloMessage name="John" />, mountNode);
`;
ReactDOM.render(<HelloMessage name="${name}" />, mountNode);
`.trim();

ReactDOM.render(
<ReactPlayground codeText={HELLO_COMPONENT} />,
Expand Down
29 changes: 17 additions & 12 deletions docs/_js/examples/markdown.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
var MARKDOWN_COMPONENT = `
var MarkdownEditor = React.createClass({
getInitialState: function() {
return {value: 'Type some *markdown* here!'};
},
handleChange: function() {
class MarkdownEditor extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.state = {value: 'Type some *markdown* here!'};
}

handleChange() {
this.setState({value: this.refs.textarea.value});
},
rawMarkup: function() {
}

getRawMarkup() {
var md = new Remarkable();
return { __html: md.render(this.state.value) };
},
render: function() {
}

render() {
return (
<div className="MarkdownEditor">
<h3>Input</h3>
Expand All @@ -21,15 +26,15 @@ var MarkdownEditor = React.createClass({
<h3>Output</h3>
<div
className="content"
dangerouslySetInnerHTML={this.rawMarkup()}
dangerouslySetInnerHTML={this.getRawMarkup()}
/>
</div>
);
}
});
}

ReactDOM.render(<MarkdownEditor />, mountNode);
`;
`.trim();

ReactDOM.render(
<ReactPlayground codeText={MARKDOWN_COMPONENT} />,
Expand Down
37 changes: 22 additions & 15 deletions docs/_js/examples/timer.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,33 @@
var TIMER_COMPONENT = `
var Timer = React.createClass({
getInitialState: function() {
return {secondsElapsed: 0};
},
tick: function() {
this.setState({secondsElapsed: this.state.secondsElapsed + 1});
},
componentDidMount: function() {
this.interval = setInterval(this.tick, 1000);
},
componentWillUnmount: function() {
class Timer extends React.Component {
constructor(props) {
super(props);
this.state = {secondsElapsed: 0};
}

tick() {
this.setState({
secondsElapsed: this.state.secondsElapsed + 1
});
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we reach a decision on whether to use the updater form here or not? Even though it doesn't matter for a Timer where state is only updating once a second, people will see this and use it elsewhere.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

}

componentDidMount() {
this.interval = setInterval(() => this.tick(), 1000);
}

componentWillUnmount() {
clearInterval(this.interval);
},
render: function() {
}

render() {
return (
<div>Seconds Elapsed: {this.state.secondsElapsed}</div>
);
}
});
}

ReactDOM.render(<Timer />, mountNode);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it would be more similar to real usage if you used document.getElementById('root') or similar here, rather than mountNode?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but this would require some further changes to how this page is set up (e.g. passing IDs as props to the code editor). Can do separately.

`;
`.trim();

ReactDOM.render(
<ReactPlayground codeText={TIMER_COMPONENT} />,
Expand Down
63 changes: 39 additions & 24 deletions docs/_js/examples/todo.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,56 @@
var TODO_COMPONENT = `
var TodoList = React.createClass({
render: function() {
var createItem = function(item) {
return <li key={item.id}>{item.text}</li>;
};
return <ul>{this.props.items.map(createItem)}</ul>;
class TodoApp extends React.Component {
constructor(props) {
super(props);
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.state = {items: [], text: ''};
}
});
var TodoApp = React.createClass({
getInitialState: function() {
return {items: [], text: ''};
},
onChange: function(e) {
this.setState({text: e.target.value});
},
handleSubmit: function(e) {
e.preventDefault();
var nextItems = this.state.items.concat([{text: this.state.text, id: Date.now()}]);
var nextText = '';
this.setState({items: nextItems, text: nextText});
},
render: function() {

render() {
return (
<div>
<h3>TODO</h3>
<TodoList items={this.state.items} />
<form onSubmit={this.handleSubmit}>
<input onChange={this.onChange} value={this.state.text} />
<input onChange={this.handleChange} value={this.state.text} />
<button>{'Add #' + (this.state.items.length + 1)}</button>
</form>
</div>
);
}
});

handleChange(e) {
this.setState({text: e.target.value});
}

handleSubmit(e) {
e.preventDefault();
var newItem = {
text: this.state.text,
id: Date.now()
};
this.setState({
items: [...this.state.items, newItem],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about just using concat to avoid ...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also - wasn't someone talking recently about, you shouldn't use this.state.foo in setState, because there's some race condition if you do it twice per update cycle? I really prefer the look of this code, but, I just want to make sure we're not suggesting something buggy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used to be concat but it looked pretty crowdy and I thought this could save some space. IMO it's not hard to guess what it does even if you don't use ES6. But happy to change back to concat if you think that was better. (Many people don't know concat() exists or what it does either.) It's also not really the point of the example, and the code is more for illustrative purposes rather than for direct learning.

Also - wasn't someone talking recently about, you shouldn't use this.state.foo in setState

Ideally you shouldn't but the alternative is too much syntax noise for this example so I think it's okay.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not quite a race condition, it's that setState is potential asynchronous and/or batched. I don't think it's a good idea for the official docs to implicitly communicate that this is okay. Nobody will know this is a problem unless we're explicit about it.

text: ''
});
}
}

class TodoList extends React.Component {
render() {
return (
<ul>
{this.props.items.map(item => (
<li key={item.id}>{item.text}</li>
))}
</ul>
);
}
}

ReactDOM.render(<TodoApp />, mountNode);
`;
`.trim();

ReactDOM.render(
<ReactPlayground codeText={TODO_COMPONENT} />,
Expand Down
20 changes: 14 additions & 6 deletions docs/_js/live_editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,14 @@ var ReactPlayground = React.createClass({

getDefaultProps: function() {
return {
transformer: function(code) {
return babel.transform(code).code;
transformer: function(code, options) {
var presets = ['react'];
if (!options || !options.skipES2015Transform) {
presets.push('es2015');
}
return Babel.transform(code, {
presets
}).code;
},
editorTabTitle: 'Live JSX Editor',
showCompiledJSTab: true,
Expand All @@ -115,15 +121,15 @@ var ReactPlayground = React.createClass({
this.setState({mode: mode});
},

compileCode: function() {
return this.props.transformer(this.state.code);
compileCode: function(options) {
return this.props.transformer(this.state.code, options);
},

render: function() {
var isJS = this.state.mode === this.MODES.JS;
var compiledCode = '';
try {
compiledCode = this.compileCode();
compiledCode = this.compileCode({skipES2015Transform: true});
} catch (err) {}

var JSContent =
Expand Down Expand Up @@ -201,13 +207,15 @@ var ReactPlayground = React.createClass({
} catch (e) { }

try {
var compiledCode = this.compileCode();
var compiledCode;
if (this.props.renderCode) {
compiledCode = this.compileCode({skipES2015Transform: true});
ReactDOM.render(
<CodeMirrorEditor codeText={compiledCode} readOnly={true} />,
mountNode
);
} else {
compiledCode = this.compileCode({skipES2015Transform: false});
eval(compiledCode);
}
} catch (err) {
Expand Down
2 changes: 1 addition & 1 deletion docs/_layouts/default.html
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<script src="/react/js/jsx.js"></script>
<script src="/react/js/react.js"></script>
<script src="/react/js/react-dom.js"></script>
<script src="/react/js/babel-browser.min.js"></script>
<script src="/react/js/babel.min.js"></script>
<script src="/react/js/live_editor.js"></script>
</head>
<body>
Expand Down