Skip to content

Commit c7d74e0

Browse files
committed
add new demo PropTypes
1 parent a20c920 commit c7d74e0

File tree

15 files changed

+219
-126
lines changed

15 files changed

+219
-126
lines changed

README.md

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,17 @@ Then play with the source files under the repo's demo* directories.
4141
## Index
4242

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

5556
---
5657

@@ -152,7 +153,69 @@ React.render(
152153

153154
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.
154155

155-
## Demo6: Finding a DOM node ([source](https://github.com/ruanyf/react-demos/blob/master/demo06/index.html))
156+
## Demo06: PropTypes ([source](https://github.com/ruanyf/react-demos/blob/master/demo06/index.html))
157+
158+
Components have many specific attributes which are called ”props” in React and can be of any type.
159+
160+
Sometimes you need a way to validate these props. You don't want users input anything into your components.
161+
162+
React has a solution for this and it's called propTypes.
163+
164+
```javascript
165+
var MyTitle = React.createClass({
166+
propTypes: {
167+
title: React.PropTypes.string.isRequired,
168+
},
169+
170+
render: function() {
171+
return <h1> {this.props.title} </h1>;
172+
}
173+
});
174+
```
175+
176+
The above component of `Mytitle` has a props of `title`. PropTypes tells React that title is required and its value should be string.
177+
178+
Now we give `Title` a number value.
179+
180+
```javascript
181+
var data = 123;
182+
183+
React.render(
184+
<MyTitle title={data} />,
185+
document.body
186+
);
187+
```
188+
189+
It means the props doesn't pass the validation, and the console will show you a error message.
190+
191+
```bash
192+
Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
193+
```
194+
195+
Visit [official doc](http://facebook.github.io/react/docs/reusable-components.html) for more PropTypes options.
196+
197+
P.S. If you want to give the props a default value, use `getDefaultProps()`.
198+
199+
```javascript
200+
var MyTitle = React.createClass({
201+
getDefaultProps : function () {
202+
return {
203+
title : 'Hello World'
204+
};
205+
},
206+
207+
render: function() {
208+
return <h1> {this.props.title} </h1>;
209+
}
210+
});
211+
212+
React.render(
213+
<MyTitle />,
214+
document.body
215+
);
216+
```
217+
218+
## Demo07: Finding a DOM node ([source](https://github.com/ruanyf/react-demos/blob/master/demo07/index.html))
156219

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

@@ -179,7 +242,7 @@ React.render(
179242

180243
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`.
181244

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

184247
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.
185248

@@ -209,7 +272,7 @@ React.render(
209272

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

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

214277
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.
215278

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

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

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

244307
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.
245308

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

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

294357
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.
295358

@@ -330,7 +393,7 @@ React.render(
330393
);
331394
```
332395
333-
## Demo11: Server-side rendering ([source](https://github.com/ruanyf/react-demos/tree/master/demo11/src))
396+
## Demo12: Server-side rendering ([source](https://github.com/ruanyf/react-demos/tree/master/demo11/src))
334397
335398
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.
336399
@@ -339,7 +402,7 @@ This demo is copied from [github.com/mhart/react-server-example](https://github.
339402
$ npm install
340403
341404
# translate all jsx file in src subdirectory to js file
342-
$ jsx src/ .
405+
$ npm run build
343406
344407
# launch http server
345408
$ node server.js
@@ -351,16 +414,16 @@ $ node server.js
351414
352415
All above demos don't use JSX compilation for clarity. In production environment, ensure to precompile JSX files before putting them online.
353416

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

356419
```bash
357-
$ npm install -g react-tools
420+
$ npm install -g babel
358421
```
359422

360-
Then precompile your JSX files(.jsx) into JavaScript(.js).
423+
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.
361424

362425
```bash
363-
$ jsx -x src/ build/
426+
$ babel src --out-dir build
364427
```
365428

366429
Put the compiled JS files into HTML.
@@ -371,7 +434,7 @@ Put the compiled JS files into HTML.
371434
<head>
372435
<title>Hello React!</title>
373436
<script src="build/react.js"></script>
374-
<!-- No need for JSXTransformer! -->
437+
<!-- No need for Browser.js! -->
375438
</head>
376439
<body>
377440
<div id="example"></div>

demo06/index.html

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,26 @@
55
<script src="../build/browser.min.js"></script>
66
</head>
77
<body>
8-
<div id="example"></div>
98
<script type="text/babel">
10-
var MyComponent = React.createClass({
11-
handleClick: function() {
12-
React.findDOMNode(this.refs.myTextInput).focus();
13-
},
14-
render: function() {
15-
return (
16-
<div>
17-
<input type="text" ref="myTextInput" />
18-
<input type="button" value="Focus the text input" onClick={this.handleClick} />
19-
</div>
20-
);
21-
}
22-
});
239

24-
React.render(
25-
<MyComponent />,
26-
document.getElementById('example')
27-
);
10+
var data = 123;
11+
12+
var MyTitle = React.createClass({
13+
propTypes: {
14+
title: React.PropTypes.string.isRequired,
15+
},
16+
17+
render: function() {
18+
return <h1> {this.props.title} </h1>;
19+
}
20+
});
21+
22+
React.render(
23+
<MyTitle title={data} />,
24+
document.body
25+
);
26+
2827
</script>
2928
</body>
3029
</html>
30+

demo07/index.html

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,24 @@
77
<body>
88
<div id="example"></div>
99
<script type="text/babel">
10-
var LikeButton = React.createClass({
11-
getInitialState: function() {
12-
return {liked: false};
13-
},
14-
handleClick: function(event) {
15-
this.setState({liked: !this.state.liked});
10+
var MyComponent = React.createClass({
11+
handleClick: function() {
12+
React.findDOMNode(this.refs.myTextInput).focus();
1613
},
1714
render: function() {
18-
var text = this.state.liked ? 'like' : 'haven\'t liked';
1915
return (
20-
<p onClick={this.handleClick}>
21-
You {text} this. Click to toggle.
22-
</p>
16+
<div>
17+
<input type="text" ref="myTextInput" />
18+
<input type="button" value="Focus the text input" onClick={this.handleClick} />
19+
</div>
2320
);
2421
}
2522
});
2623

2724
React.render(
28-
<LikeButton />,
25+
<MyComponent />,
2926
document.getElementById('example')
3027
);
3128
</script>
3229
</body>
3330
</html>
34-

demo08/index.html

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,30 @@
55
<script src="../build/browser.min.js"></script>
66
</head>
77
<body>
8+
<div id="example"></div>
89
<script type="text/babel">
9-
var Input = React.createClass({
10-
getInitialState: function() {
11-
return {value: 'Hello!'};
12-
},
13-
handleChange: function(event) {
14-
this.setState({value: event.target.value});
15-
},
16-
render: function () {
17-
var value = this.state.value;
18-
return (
19-
<div>
20-
<input type="text" value={value} onChange={this.handleChange} />
21-
<p>{value}</p>
22-
</div>
23-
);
24-
}
25-
});
10+
var LikeButton = React.createClass({
11+
getInitialState: function() {
12+
return {liked: false};
13+
},
14+
handleClick: function(event) {
15+
this.setState({liked: !this.state.liked});
16+
},
17+
render: function() {
18+
var text = this.state.liked ? 'like' : 'haven\'t liked';
19+
return (
20+
<p onClick={this.handleClick}>
21+
You {text} this. Click to toggle.
22+
</p>
23+
);
24+
}
25+
});
2626

27-
React.render(<Input/>, document.body);
27+
React.render(
28+
<LikeButton />,
29+
document.getElementById('example')
30+
);
2831
</script>
2932
</body>
3033
</html>
34+

demo09/index.html

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,25 @@
66
</head>
77
<body>
88
<script type="text/babel">
9-
var Hello = React.createClass({
10-
getInitialState: function () {
11-
return {
12-
opacity: 1.0
13-
};
9+
var Input = React.createClass({
10+
getInitialState: function() {
11+
return {value: 'Hello!'};
1412
},
15-
16-
componentDidMount: function () {
17-
this.timer = setInterval(function () {
18-
var opacity = this.state.opacity;
19-
opacity -= .05;
20-
if (opacity < 0.1) {
21-
opacity = 1.0;
22-
}
23-
this.setState({
24-
opacity: opacity
25-
});
26-
}.bind(this), 100);
13+
handleChange: function(event) {
14+
this.setState({value: event.target.value});
2715
},
28-
2916
render: function () {
17+
var value = this.state.value;
3018
return (
31-
<div style={{opacity: this.state.opacity}}>
32-
Hello {this.props.name}
19+
<div>
20+
<input type="text" value={value} onChange={this.handleChange} />
21+
<p>{value}</p>
3322
</div>
3423
);
3524
}
3625
});
3726

38-
React.render(
39-
<Hello name="world"/>,
40-
document.body
41-
);
27+
React.render(<Input/>, document.body);
4228
</script>
4329
</body>
4430
</html>

0 commit comments

Comments
 (0)