This is a collection of simple demos of React.js.
These demos are purposely written in a simple and clear style. You will find no difficulty in following them to learn the powerful library.
First, copy the repo into your disk.
$ git clone git@github.com:ruanyf/react-demos.git
Then play with the source files under the repo's demo* directories.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<script src="https://github.com/ruanyf/react-demos/raw/main/build/react.development.js"></script>
<script src="https://github.com/ruanyf/react-demos/raw/main/build/react-dom.development.js"></script>
<script src="https://github.com/ruanyf/react-demos/raw/main/build/babel.min.js"></script>
</head>
<body>
<script type="text/babel">
// ** Our code goes here! **
</script>
</body>
</html>
The template syntax in React is called JSX. JSX allows you to use HTML tags in JavaScript code. ReactDOM.render() is the method which translates JSX into HTML and renders it into the specified DOM node.
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('example')
);
To actually perform the transformation in the browser, you must use <script type="text/babel"> to indicate JSX code, and include babel.min.js, which is a browser version of Babel and can be found in the babel-core@6 npm release.
Before v0.14, React used JSTransform.js to translate <script type="text/jsx">, but this is now deprecated (more info).
You can also use JavaScript within JSX. Angle brackets (<) symbolize the beginning of HTML syntax, while curly brackets ({) represent the beginning of JavaScript syntax.
var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
{
names.map(function (name) {
return
Hello, {name}!
})
}
,
document.getElementById('example')
);
If a JavaScript variable is an array, JSX will implicitly concat all members of the array.
var arr = [
<h1>Hello world!</h1>,
<h2>React is awesome</h2>,
];
ReactDOM.render(
{arr}
,
document.getElementById('example')
);
class ComponentName extends React.Component creates a component class, which implements a render method to return a component instance of the class.
Before v16.0, React used React.createClass() to create a component class, but this is now deprecated (more info).
class HelloMessage extends React.Component {
render() {
return <h1>Hello {this.props.name}</h1>;
}
}
ReactDOM.render(
<HelloMessage name="John" />,
document.getElementById('example')
);
You can use this.props.[attribute] to access the attributes of a component. Example: this.props.name of <HelloMessage name="John" /> is John.
Please remember the first letter of the component's name must be capitalized, otherwise, React will throw an error. For instance, HelloMessage as a component's name is OK, but helloMessage is not allowed. And a React component should only have one top child node.
// wrong
class HelloMessage extends React.Component {
render() {
return <h1>
Hello {this.props.name}
</h1>
some text
;
}
}
// correct
class HelloMessage extends React.Component {
render() {
return
<h1>Hello {this.props.name}</h1>
some text
;
}
}
React uses this.props.children to access a component's children nodes.
class NotesList extends React.Component {
render() {
return (
<ol>
{
React.Children.map(this.props.children, function (child) {
return <li>{child}</li>;
})
}
</ol>
);
}
}
ReactDOM.render(
<NotesList>
<span>hello</span>
<span>world</span>
</NotesList>,
document.getElementById('example')
);
Please be mindful that the value of this.props.children has three possibilities. If the component has no child node, the value is undefined; If it has a single child node, the value will be an object; If it has multiple children nodes, the result is an array. Keep this in mind as you code.
React gave us a utility React.Children for dealing with the opaque data structure of this.props.children. You can use React.Children.map to iterate this.props.children without worrying if its data type is undefined or object. Check official document for more methods React.Children offers.
Components in React have many specific attributes which are called props and can be of any type.
Sometimes you need a way to validate these props. You don't want users have the freedom to input anything into your components.
React has a solution for this and it's called PropTypes.
class MyTitle extends React.Component {
static propTypes = {
title: PropTypes.string.isRequired,
}
render() {
return <h1> {this.props.title} </h1>;
}
}
The above component MyTitle has a prop of title. PropTypes tells React that the title is required and its value should be a string.
Now we give Title a number value.
var data = 123;
ReactDOM.render(
<MyTitle title={data} />,
document.getElementById('example')
);
Here, the prop doesn't pass the validation, and the console will show you an error message:
Warning: Failed propType: Invalid prop `title` of type `number` supplied to `MyTitle`, expected `string`.
Visit official doc for more PropTypes options.
P.S. If you want to give the props a default value, use defaultProps.
class MyTitle extends React.Component {
constructor(props) {
super(props)
}
static defaultProps = {
title: 'Hello World',
}
render() {
return <h1> {this.props.title} </h1>;
}
}
ReactDOM.render(
<MyTitle />,
document.getElementById('example')
);
React.PropTypes has moved into a different package since React v15.5. (more info).
Sometimes you need to reference a DOM node in a component. React gives you the ref attribute to attach a DOM node to instance created by React.createRef().
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.myTextInput = React.createRef();
this.handleClick = this.handleClick.bind(this)
}
handleClick() {
this.myTextInput.current.focus();
}
render() {
return (
<input type="text" ref={this.myTextInput} />
<input type="button" value="Focus the text input" onClick={this.handleClick} />
);
}
}
ReactDOM.render(
<MyComponent />,
document.getElementById('example')
);
Please be mindful that you could do that only after this component has been mounted into the DOM, otherwise you get null.
React thinks of component as state machines, and uses this.state to hold component's state, this.setState() to update this.state and re-render the component.
class LikeButton extends React.Component {
constructor(props) {
super(props)
this.state = {
liked: false
}
this.handleClick = this.handleClick.bind(this)
}
handleClick(event) {
this.setState({ liked: !this.state.liked });
}
render() {
var text = this.state.liked ? 'like' : 'haven\'t liked';
return (
You {text} this. Click to toggle.
);
}
}
ReactDOM.render(
<LikeButton />,
document.getElementById('example')
);
You could use component attributes to register event handlers, just like onClick, onKeyDown, onCopy, etc. Official Document has all supported events.
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.
Since that, the value attribute of Form components, such as <input>, <textarea>, and <option>, is unaffected by any user input. If you wanted to access or update the value in response to user input, you could use the onChange event.
class Input extends React.Component {
constructor(props) {
super(props)
this.state = {value: 'Hello!'}
this.handleChange = this.handleChange.bind(this)
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
var value = this.state.value;
return (
<input type="text" value={value} onChange={this.handleChange} />
{value}
);
}
}
ReactDOM.render(<Input/>, document.getElementById('example'));
More information on official document.
Components have three main parts of their 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.
class Hello extends React.Component {
constructor(props) {
super(props)
this.state = {opacity: 1.0};
}
componentDidMount() {
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);
}
render() {
return (
Hello {this.props.name}
);
}
}
ReactDOM.render(
<Hello name="world"/>,
document.getElementById('example')
);
The following is a whole list of lifecycle methods.
this.setState doesn't work here.this.getDOMNode().this.getDOMNode() for updates.$ claude mcp add react-demos \
-- python -m otcore.mcp_server <graph>