Skip to content

Commit

Permalink
add new demo PropTypes
Browse files Browse the repository at this point in the history
  • Loading branch information
ruanyf committed Aug 21, 2015
1 parent a20c920 commit c7d74e0
Show file tree
Hide file tree
Showing 15 changed files with 219 additions and 126 deletions.
107 changes: 85 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,17 @@ Then play with the source files under the repo's demo* directories.
## Index

1. [Render JSX](#demo01-render-jsx-source)
2. [Use JavaScript in JSX](#demo02-use-javascript-in-jsx-source)
3. [Use array in JSX](#demo03-use-array-in-jsx-source)
4. [Define a component](#demo04-define-a-component-source)
5. [this.props.children](#demo05-thispropschildren-source)
6. [Finding a DOM node](#demo6-finding-a-dom-node-source)
7. [this.state](#demo07-thisstate-source)
8. [Form](#demo08-form-source)
9. [Component Lifecycle](#demo09-component-lifecycle-source)
10. [Ajax](#demo10-ajax-source)
11. [Server-side rendering](#demo11-server-side-rendering-source)
1. [Use JavaScript in JSX](#demo02-use-javascript-in-jsx-source)
1. [Use array in JSX](#demo03-use-array-in-jsx-source)
1. [Define a component](#demo04-define-a-component-source)
1. [this.props.children](#demo05-thispropschildren-source)
1. [PropTypes](#demo06-proptypes-source)
1. [Finding a DOM node](#demo7-finding-a-dom-node-source)
1. [this.state](#demo08-thisstate-source)
1. [Form](#demo09-form-source)
1. [Component Lifecycle](#demo10-component-lifecycle-source)
1. [Ajax](#demo11-ajax-source)
1. [Server-side rendering](#demo12-server-side-rendering-source)

---

Expand Down Expand Up @@ -152,7 +153,69 @@ React.render(

Please be minded that only if the component has more than one child node, you could take `this.props.children` as an array, otherwise `this.props.children.map` throws a TypeError.

## Demo6: Finding a DOM node ([source](https://github.com/ruanyf/react-demos/blob/master/demo06/index.html))
## Demo06: PropTypes ([source](https://github.com/ruanyf/react-demos/blob/master/demo06/index.html))

Components have many specific attributes which are called ”props” in React and can be of any type.

Sometimes you need a way to validate these props. You don't want users input anything into your components.

React has a solution for this and it's called propTypes.

```javascript
var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},

render: function() {
return <h1> {this.props.title} </h1>;
}
});
```

The above component of `Mytitle` has a props of `title`. PropTypes tells React that title is required and its value should be string.

Now we give `Title` a number value.

```javascript
var data = 123;

React.render(
<MyTitle title={data} />,
document.body
);
```

It means the props doesn't pass the validation, and the console will show you a error message.

```bash
Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
```

Visit [official doc](http:https://facebook.github.io/react/docs/reusable-components.html) for more PropTypes options.

P.S. If you want to give the props a default value, use `getDefaultProps()`.

```javascript
var MyTitle = React.createClass({
getDefaultProps : function () {
return {
title : 'Hello World'
};
},

render: function() {
return <h1> {this.props.title} </h1>;
}
});

React.render(
<MyTitle />,
document.body
);
```

## Demo07: Finding a DOM node ([source](https://github.com/ruanyf/react-demos/blob/master/demo07/index.html))

Sometimes you need to reference a DOM node in a component. React gives you React.findDOMNode() to find it.

Expand All @@ -179,7 +242,7 @@ React.render(

The desired DOM node should have a `ref` attribute, and `React.findDOMNode(this.refs.[refName])` would return the corresponding DOM node. Please be minded that you could do that only after this component has been mounted into the DOM, otherwise you get `null`.

## Demo07: this.state ([source](https://github.com/ruanyf/react-demos/blob/master/demo07/index.html))
## Demo08: this.state ([source](https://github.com/ruanyf/react-demos/blob/master/demo08/index.html))

React thinks of component as state machines, and uses `this.state` to hold component's state, `getInitialState()` to initialize `this.state`(invoked before a component is mounted), `this.setState()` to update `this.state` and re-render the component.

Expand Down Expand Up @@ -209,7 +272,7 @@ React.render(

You could use component attributes to register event handlers, just like `onClick`, `onKeyDown`, `onCopy`, etc. Official Document has all [supported events](http:https://facebook.github.io/react/docs/events.html#supported-events).

## Demo08: Form ([source](https://github.com/ruanyf/react-demos/blob/master/demo08/index.html))
## Demo09: Form ([source](https://github.com/ruanyf/react-demos/blob/master/demo09/index.html))

According to React's design philosophy, `this.state` describes the state of component and is mutated via user interactions, and `this.props` describes the properties of component and is stable and immutable.

Expand Down Expand Up @@ -239,7 +302,7 @@ React.render(<Input/>, document.body);

More information on [official document](http:https://facebook.github.io/react/docs/forms.html).

## Demo09: Component Lifecycle ([source](https://github.com/ruanyf/react-demos/blob/master/demo09/index.html))
## Demo10: Component Lifecycle ([source](https://github.com/ruanyf/react-demos/blob/master/demo10/index.html))

Components have three main parts of [their lifecycle](https://facebook.github.io/react/docs/working-with-the-browser.html#component-lifecycle): Mounting(being inserted into the DOM), Updating(being re-rendered) and Unmounting(being removed from the DOM). React provides hooks into these lifecycle part. `will` methods are called right before something happens, and `did` methods which are called right after something happens.

Expand Down Expand Up @@ -289,7 +352,7 @@ The following is [a whole list of lifecycle methods](http:https://facebook.github.io/r
- componentWillReceiveProps(object nextProps): invoked when a mounted component receives new props.
- shouldComponentUpdate(object nextProps, object nextState): invoked when a component decides whether any changes warrant an update to the DOM.

## Demo10: Ajax ([source](https://github.com/ruanyf/react-demos/blob/master/demo10/index.html))
## Demo11: Ajax ([source](https://github.com/ruanyf/react-demos/blob/master/demo11/index.html))

How to get the data of a component from a server or an API provider? The answer is using Ajax to fetch data in the event handler of `componentDidMount`. When the server response arrives, store the data with `this.setState()` to trigger a re-render of your UI.

Expand Down Expand Up @@ -330,7 +393,7 @@ React.render(
);
```
## Demo11: Server-side rendering ([source](https://github.com/ruanyf/react-demos/tree/master/demo11/src))
## Demo12: Server-side rendering ([source](https://github.com/ruanyf/react-demos/tree/master/demo11/src))
This demo is copied from [github.com/mhart/react-server-example](https://github.com/mhart/react-server-example), but I rewrote it with JSX syntax.
Expand All @@ -339,7 +402,7 @@ This demo is copied from [github.com/mhart/react-server-example](https://github.
$ npm install
# translate all jsx file in src subdirectory to js file
$ jsx src/ .
$ npm run build
# launch http server
$ node server.js
Expand All @@ -351,16 +414,16 @@ $ node server.js
All above demos don't use JSX compilation for clarity. In production environment, ensure to precompile JSX files before putting them online.

First, install the command-line tools.
First, install the command-line tools [Babel](https://babeljs.io/docs/usage/cli/).

```bash
$ npm install -g react-tools
$ npm install -g babel
```

Then precompile your JSX files(.jsx) into JavaScript(.js).
Then precompile your JSX files(.jsx) into JavaScript(.js). Compiling the entire src directory and output it to the build directory, you may use the option --out-dir or -d.

```bash
$ jsx -x src/ build/
$ babel src --out-dir build
```

Put the compiled JS files into HTML.
Expand All @@ -371,7 +434,7 @@ Put the compiled JS files into HTML.
<head>
<title>Hello React!</title>
<script src="build/react.js"></script>
<!-- No need for JSXTransformer! -->
<!-- No need for Browser.js! -->
</head>
<body>
<div id="example"></div>
Expand Down
36 changes: 18 additions & 18 deletions demo06/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
var MyComponent = React.createClass({
handleClick: function() {
React.findDOMNode(this.refs.myTextInput).focus();
},
render: function() {
return (
<div>
<input type="text" ref="myTextInput" />
<input type="button" value="Focus the text input" onClick={this.handleClick} />
</div>
);
}
});

React.render(
<MyComponent />,
document.getElementById('example')
);
var data = 123;

var MyTitle = React.createClass({
propTypes: {
title: React.PropTypes.string.isRequired,
},

render: function() {
return <h1> {this.props.title} </h1>;
}
});

React.render(
<MyTitle title={data} />,
document.body
);

</script>
</body>
</html>

20 changes: 8 additions & 12 deletions demo07/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,28 +7,24 @@
<body>
<div id="example"></div>
<script type="text/babel">
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
var MyComponent = React.createClass({
handleClick: function() {
React.findDOMNode(this.refs.myTextInput).focus();
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
<div>
<input type="text" ref="myTextInput" />
<input type="button" value="Focus the text input" onClick={this.handleClick} />
</div>
);
}
});

React.render(
<LikeButton />,
<MyComponent />,
document.getElementById('example')
);
</script>
</body>
</html>

40 changes: 22 additions & 18 deletions demo08/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,30 @@
<script src="../build/browser.min.js"></script>
</head>
<body>
<div id="example"></div>
<script type="text/babel">
var Input = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},
handleChange: function(event) {
this.setState({value: event.target.value});
},
render: function () {
var value = this.state.value;
return (
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});
var LikeButton = React.createClass({
getInitialState: function() {
return {liked: false};
},
handleClick: function(event) {
this.setState({liked: !this.state.liked});
},
render: function() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
<p onClick={this.handleClick}>
You {text} this. Click to toggle.
</p>
);
}
});

React.render(<Input/>, document.body);
React.render(
<LikeButton />,
document.getElementById('example')
);
</script>
</body>
</html>

34 changes: 10 additions & 24 deletions demo09/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,39 +6,25 @@
</head>
<body>
<script type="text/babel">
var Hello = React.createClass({
getInitialState: function () {
return {
opacity: 1.0
};
var Input = React.createClass({
getInitialState: function() {
return {value: 'Hello!'};
},

componentDidMount: function () {
this.timer = setInterval(function () {
var opacity = this.state.opacity;
opacity -= .05;
if (opacity < 0.1) {
opacity = 1.0;
}
this.setState({
opacity: opacity
});
}.bind(this), 100);
handleChange: function(event) {
this.setState({value: event.target.value});
},

render: function () {
var value = this.state.value;
return (
<div style={{opacity: this.state.opacity}}>
Hello {this.props.name}
<div>
<input type="text" value={value} onChange={this.handleChange} />
<p>{value}</p>
</div>
);
}
});

React.render(
<Hello name="world"/>,
document.body
);
React.render(<Input/>, document.body);
</script>
</body>
</html>
Loading

0 comments on commit c7d74e0

Please sign in to comment.