We allow assembly into separate code reuse code fragment, which is a very important concept of
1, the function components
We can write a JavaScript function definition component
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// 通过 function 定义组件,函数返回一个 React 元素
// 需要注意的是,组件名称必须以大写字母开头
// 因为 React 会将以小写字母开头的组件视为原生 DOM 标签
function SayHello() {
return <h1>Hello World</h1>;
};
// React 元素不仅仅是 DOM 标签,也可以是自定义组件
const element = <SayHello />;
ReactDOM.render(
element,
document.getElementById('app')
);
</script>
</body>
</html>
2, class components
We can also custom components by using the class, and it is recommended to use this way
Because the use of class definition component allows us to add some additional methods and properties for the component, so that the assembly has better scalability
<!DOCTYPE html>
<html>
<head>
<title>Demo</title>
<script src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/babel-standalone"></script>
</head>
<body>
<div id="app"></div>
<script type="text/babel">
// class 组件必须继承 React.Component
class SayHello extends React.Component {
// 使用 render() 函数返回一个 React 元素
// 注意,该元素必须只能具有一个顶层标签
render() {
return <h1>Hello World</h1>;
}
};
// 使用组件的方法是一样的
const element = <SayHello />;
ReactDOM.render(
element,
document.getElementById('app')
);
</script>
</body>
</html>
3、props
When React custom component element, the received attribute JSX conversion component passed as a single object, the object will be referred to as props
In this way, we can pass the data to the component
class SayHello extends React.Component {
render() {
// 在组件中通过 this.props 访问 props
// 注意,props 应该是只读的,也就是说我们不应该修改它的取值
return <h1>Hello { this.props.name }</h1>;
}
};
// 这里将属性转换为 props 对象并传入组件
const element = <SayHello name='Alice' />;
ReactDOM.render(
element,
document.getElementById('app')
);
4, a custom function
By custom function, we can add additional methods to the class assembly
class SayHello extends React.Component {
// 构造函数
constructor(props) {
// 将 props 传递到父类构造函数
super(props);
}
// 自定义函数
format(name) {
return name.substring(0,1).toUpperCase() + name.substring(1);
}
render() {
// 通过 this.functionName() 调用自定义函数
let formatedName = this.format(this.props.name);
return <h1>Hello { formatedName }</h1>;
}
};
const element = <SayHello name='alice'/>;
ReactDOM.render(
element,
document.getElementById('app')
);
5、state
By state, we can add additional data class components
Data and state are props assembly, except that the props are passed from a parent component data, and state data are private component
class Timer extends React.Component {
constructor(props) {
super(props);
// 初始化 state
this.state = { date: new Date() };
}
render() {
// 通过 this.state 访问 state
return (
<div>
<h1>Hello</h1>
<p>现在是{ this.state.date.toLocaleTimeString() }</p>
</div>
)
}
};
const element = <Timer />;
ReactDOM.render(
element,
document.getElementById('app')
);
Using state there are several places that require special attention:
- Do not directly modify the state
We can directly access the state, but can not directly modify the state, for example,
this.state.date = new Date()
// 这样的语句并不会重新渲染组件
To modify the state and re-rendering component, we can use this.setState()
, for example,
this.setState({date: new Date()})
But the only constructor is a special place where we can directly in the constructor function this.state
assignment, for example,
this.state = { date: new Date() }
- Update state is asynchronous
For performance reasons, React would more likely setState()
call into a call to merge
Therefore, this.props
and this.state
may be updated asynchronously, so do not rely on their values to update the state
this.setState({
counter: this.state.counter + this.props.increment
})
// 这样的代码可能不会正常更新 counter
To solve this problem, allowing setState()
to receive a function as an argument, not an object
The first argument is a state, the second parameter for this update is applied when the props, returns an object
this.setState((state, props) => ({
counter: state.counter + props.increment
}));
- state updates will be merged
setState()
Object calls will provide the merged into the current state, rather than replace
In other words, if we initialize state in the constructor as follows:
constructor(props) {
super(props);
this.state = {
name: 'Alice',
phone: '12345679810'
};
}
Then call the setState()
method to update state as follows:
this.setState({
phone: '10987654321'
})
In this case, the data should be in the state { name: 'Alice', phone: '10987654321'}
, rather than{ phone: '10987654321' }
6, Life Cycle
Each component has a life cycle, will include life-cycle approach, we can override these methods so that components to complete a specific action at a specific stage
Life cycle of components can be divided into three stages, each stage of the life cycle approach calling sequence as follows:
Mount: Fires when the assembly is inserted into the DOM
constructor()
: Before calling mount components, mainly used to initialize the state or the event handler binding instanceDo not use this
setState()
method if you need to initialize state, can be directlythis.state
assignedrender()
: Class components only method that must be implemented, this function should be a pure functionThat is to say, without modification state of each call to return the same result, and it does not interact with the browser
componentDidMount()
: After calls mount assembly, mainly depends on the DOM node initialization operationFor example instantiation or add a subscription request, may be used herein
setState()
methods
Updated: Triggered when props or state assembly changes
render()
componentDidUpdate()
: After the update call, but will not perform for the first time renderingDOM operations may be performed here, and may use a
setState()
method, but must be included in a conditional statement which
Uninstall: Triggered when the assembly is removed from the DOM
componentWillUnmount()
: Called before uninstalling componentsYou should not use this
setState()
method, because after uninstalling components, will never be re-rendered, it will not remount
class Timer extends React.Component {
// 生命周期方法,在挂载前调用
constructor(props) {
super(props);
// 初始化 state
this.state = { date: new Date() };
}
// 自定义方法
tick() {
// 通过 this.setState() 修改 state
this.setState({
date: new Date()
})
}
// 生命周期方法,在挂载后调用
componentDidMount() {
this.timerID = setInterval(() => this.tick(), 1000)
}
// 生命周期方法,在卸载前调用
componentWillUnmount() {
clearInterval(this.timerID)
}
// 生命周期方法,在挂载或更新时调用
render() {
// 通过 this.state 访问 state
return (
<div>
<h1>Hello</h1>
<p>现在是{ this.state.date.toLocaleTimeString() }</p>
</div>
)
}
};
const element = <Timer />;
ReactDOM.render(
element,
document.getElementById('app')
);
[Read More React series of articles, look React study notes ]