-
Notifications
You must be signed in to change notification settings - Fork 405
/
09-component-classes.html
101 lines (86 loc) · 3.46 KB
/
09-component-classes.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
<!doctype html>
<title>09 Component Classes - React From Zero</title>
<script src="https://unpkg.com/react@16.4.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.4.0/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/prop-types@15.6.1/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script src="https://unpkg.com/create-react-class@15.6.3/create-react-class.js">
// React.createClass was removed from React 16, it's now a own package
</script>
<div id="app"></div>
<script type="text/babel">
// Often a component needs to maintain some internal state
// for example if there is an interaction involved
// in this case a component function is not sufficient
// the component function can only have properties and no state
// we need a component class with a render function
var MyComponent = createReactClass({
// used for type-checking of the properties
// same as with the component function
propTypes: {
color: PropTypes.string
},
// this method sets default values for missing properties
// it will be called by React
// before the components gets mounted into the DOM
getDefaultProps: function() {
return { color: "green" };
},
// this method sets the initial state for the component
// it will be called by React
// before the components gets mounted into the DOM
// if this method is missing, this.state will be undefined
getInitialState: function() {
// The state can be any JavaScript value, often it is an object
return { times: 0 };
},
// this method handles all the clicks on the <span> element
handleClick: function() {
// setState() can be called with an object that contains the new
// state. Normally this triggers a call of render(), but React can
// batch multiple calls and defer the render() call (make the call
// asynchronous). To prevent this, setState can take a callback
// instead.
// This can lead to unexpected behavior, if we rely on this.state
// or this.props for our calculations
// this.setState({times: this.state.times + 1})
// The callback version doesn't have this problem, it gets the
// right state and props at time of the update
this.setState(function(prevState, props) {
return { times: prevState.times + 1 };
});
},
// this method will be called by React
// after the component got mounted into the DOM
// also every time this.setState() was called
// it's like the component function from before
// but without a props argument
render: function() {
// using the prop given by the creator of this component
// properties are now in this.props instead of the props argument
var style = { color: this.props.color };
// returning an element with a click-handler and the props and
// state values. state is stored in this.state
return (
<span onClick={this.handleClick} style={style}>
Clicked {this.state.times} times
</span>
);
}
});
// creating some instances of the interactive stateful component class
// one with default color
// Everything works exactly like with the simpler component functions
// The interface has not changed for the user of this component
var reactElement = (
<div>
<MyComponent color="red" />
<br />
<MyComponent color="blue" />
<br />
<MyComponent />
</div>
);
var renderTarget = document.getElementById("app");
ReactDOM.render(reactElement, renderTarget);
</script>