博客
zyzcos.gitee.io
与第三方库协同
感觉目前的项目都是纯React、或者纯Vue,这种集成协同的技巧,感觉先不用学。
深入学习JSX
什么是JSX
JSX
是React.creamentElement(component,porps,...children)
的语法糖
JSX一些语法
- 只要调用了
React组件
,该JSX内就要引入React
import React from 'react';
import CustomButton from './CustomButton';
function WarningButton() {
// 另一种形式:return React.createElement('CustomButton',{color:'red'},null);
return <CustomButton color="red" />;
}
因为
<CustomButton color='red'>
是JSX语法,本质就是React.createElement的语法糖,所以要引入React
- 可以使用
.语法
假如一个
modules
抛出若干组件
import React from 'react';
import MyComponents from './MyComponents'; //该模块抛出了componentA、componentB两个组件
function ComponentA(props) {
return <MyComponents.ComponentA color='red'/>
}
- 组件命名必须大写字母开头
因为在JSX语法中,
小写开头
会被认为是HTML内置标签
,从而导致无法解析。
JSX中的Props
- 表达式可以放在
Props
中 - 表达式中不能使用
if
、for
Props
的默认值为true
// 两者等价
<MyTextBox autocomplete />
<MyTextBox autocomplete={true} />
- 属性展开操作
function ComponentA(props){
return <Hello {...props}>
}
- 过滤属性再展开操作
function ComponentA(props){
const { uselessProps1, uselessProps2 , ...other } = props;
return <Hello {...other}>
}
- 特定属性:
props.children
代表子元素
性能优化
先放一下,等学完全部再回来看。
Portals
ReactDOM.createPortals(child,container)
使
子节点
渲染到存在于父组件之外
的DOM节点
中
为什么要使用Portals
可以使得带有操作
和动态渲染
效果的React组件,不局限于React父组件中
如何使用?
class App extends React.Component{
constructor(props){
super(props);
this.state = {
className:app
}
}
render(){
// 一般正常渲染到<App>中
return (
<div class={ className }>
{ this.props.children }
</div>
)
// 使用Protals进行渲染,并渲染到body上面
return ReactDOM.createPortal(
<div class={ className }>
{ this.props.children }
</div>,
document.body
)
}
}
有什么应用场景
一般用于
对话框
、悬浮卡
、提示框
Profiler API
Profiler的作用
测量React应用渲染时间成本
以及渲染代价
Profiler的使用
Profiler
需要两个props
- id
- 回调函数
class Test extends React.Component{
constructor(props){
super(props);
}
callback(
id, // 发生提交的 Profiler 树的 “id”
phase, // "mount" (如果组件树刚加载) 或者 "update" (如果它重渲染了)之一
actualDuration, // 本次更新 committed 花费的渲染时间
baseDuration, // 估计不使用 memoization 的情况下渲染整颗子树需要的时间
startTime, // 本次更新中 React 开始渲染的时间
commitTime, // 本次更新中 React committed 的时间
interactions // 属于本次更新的 interactions 的集合
){
// 逻辑代码:如输出渲染时间等。
}
render(){
return (
<App>
<Profiler id='Navigation' onRender={ callback }>
<Navigation {...props} />
</Profiler>
</App>
)
}
}
非ES6定义组件
可能使不习惯,觉得不使用ES6很不方便
- 使用
create-react-class
进行定义
var createReactClass = require('create-react-class');
var Greeting = createReactClass({
render: function() {
return <h1>Hello, {this.props.name}</h1>;
}
});
- 声明默认
Props
> ES6
```JS
class Greeting extends React.Component{
// .....
}
Greeting.defaultProps = {
name:'Fleven'
}
```
> 非ES6
```JS
var Greeting = createReactClass({
getDefaultProps:function(){
return {
name:'Fleven'
}
}
})
```
- 初始化
State
> ES6
```JS
class App extends React.Component {
constructor(props){
super(props);
this.state = { count: props.initCount }
}
}
```
> 非ES6
```JS
var App = createReactClass({
getInitialState:function(){
return { count:this.props.initCount }
}
})
```
- 事件绑定
> ES6,需要在`构造器`中声明`this.handleClick = this.handleClick.bind(this)`
> 非ES6,直接定义就可以,体会自动绑定的
不使用JSX
使用
createElement
关于createElement
的使用,在Vue.js
中就学过,暂时不再记录了。
Refs
Refs的作用
提供了一种,允许我们访问
DOM节点
或render方法创建的React元素
如何使用Refs
class App extends React.Component {
constructor(props){
super(props);
this.appRef = React.createRef(); //1. 创建Refs实例
this.handleFocus = this.handleFocus.bind(this);
}
handleFocus(){
// 3.可以在函数中。操作Refs实例,从而操作其绑定的DOM
this.appRef.current.focus(); //current属性,代表绑定的DOM节点
}
render(){
// 2.将创建的Refs实例,绑定在DOM上
retrun (
<>
<input ref={ this.appRef } />
<button onClick={ this.handleFocus }>聚焦</button>
</>
)
}
}
注意:
- 不能再
函数组件
中使用,因为函数组件
没有实例.
回调Refs
通过
回调函数
的形式,接收Refs,从而控制
Refs的创建
和删除
。
class CustomTextInput extends React.Component{
constructor(props){
super(props);
this.textInput = null;
// 设置Refs节点
this.setTextInputRef = element =>{
this.textInput = element;
}
// 对Refs节点的操作
this.focusTextInput = ()=>{
if(this.textInput){
this.textInput.focus();
}
}
}
componentDidMount() {
// 组件挂载后,让文本框自动获得焦点
this.focusTextInput();
}
componentWillUnmount() {
this.testInput = null; //卸载Refs实例
}
render(){
return(
<div>
<input
type="text"
ref={ this.setTextInputRef }
/>
<input
type="button"
value="聚焦"
onClick={ this.focusTextInput }
/>
</div>
)
}
}