总体认识
下面是一个简单的组件,来建立起对React的总体认识
import React from 'react';
import ReactDOM from 'react-dom/client';
class Content extends React.Component {
render() {
return (
<div>
This is {this.props.name}
</div>
)
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Content name={'Momo'}/>)
组件
React是建立在组件的基础上的
组件的核心概念:
- props
- state
props
props 是组件的属性,由外部通过 JSX 属性传入,初始设置完成,可以认为 this.props 是不可更改的,所以不要轻易更改 this.props 里面的值。
state
state 是组件的当前状态,可以把组件简单看成一个“状态机”,根据状态 state 呈现不同的 UI 展示。
一旦状态(数据)更改,组件就会自动调用 render 重新渲染 UI,这个更改的动作会通过 this.setState 方法来触发。
组件的生命周期:
生命周期函数
1. 装载组件触发
componentWillMount
只会在装载之前调用一次,在 render 之前调用,你可以在这个方法里面调用 setState 改变状态,并且不会导致额外调用一次 render
componentDidMount
只会在装载完成之后调用一次,在render之后调用,从这里开始可以通过 ReactDOM.findDOMNode(this) 获取到组件的 DOM 节点。
2. 更新组件触发
这些方法不会在首次 render 组件的周期调用
componentWillReceiveProps shouldComponentUpdate componentWillUpdate componentDidUpdate
3. 卸载组件触发
componentWillUnmount
JSX
React 提出了一种语法叫 JSX ,它将 HTML 直接嵌入了 JS 代码里面
利用 JSX 编写 DOM 结构,可以用原生的 HTML 标签,也可以直接像普通标签一样引用 React 组件。这两者约定通过大小写来区分,小写的字符串是 HTML 标签,大写开头的变量是 React 组件。
使用 HTML 标签:
import React from 'react';
import ReactDOM from 'react-dom/client';
const content = <div classname='content' />
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Content name={'Momo'}/>)
HTML 里的 class 在 JSX 里要写成 className,因为 class 在 JS 里是保留关键字。同理某些属性比如 for 要写成 htmlFor。
使用组件:
import React from 'react';
import { render } from 'react-dom';
import Content from './Content';
const myContent = <Content name={'Momo'} />;
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(myContent)
// 使用 JavaScript 表达式
// 属性值使用表达式,只要用 {} 替换 "":
// Input (JSX):
var person = <Person name={window.isLoggedIn ? window.name : ''} />;
// Output (JS):
var person = React.createElement(
Person,
{name: window.isLoggedIn ? window.name : ''}
);
子组件也可以作为表达式使用:
// Input (JSX):
var content = <Container>{window.isLoggedIn ? <Nav /> : <Login />}</Container>;
// Output (JS):
var content = React.createElement(
Container,
null,
window.isLoggedIn ? React.createElement(Nav) : React.createElement(Login)
);
Virtual DOM
当组件状态 state 有变化的时候,React 会自动调用组件的 render 方法重新渲染整个组件的 UI。
由于如果整体大面积的操作DOM,在性能上是不太友好的,所以和Vue类似,React 实现了一个Virtual DOM(虚拟DOM)
组件 DOM 结构会映射到这个 Virtual DOM 上,React 在 Virtual DOM 上实现了一个 diff 算法,当要重新渲染整个组件的时候,React会通过这个diff算法找到真正要变更的 DOM 节点,再将这个修改更新到浏览器实际的 DOM 节点上,所以实际上并没有渲染整个 DOM 树,这个 Virtual DOM 是一个纯粹的 JS 数据结构,所以性能会比原生 DOM 快很多。
Webpack 配置 React 开发环境
Webpack 是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能。
假设我们在当前工程目录有一个入口文件 entry.js,React 组件放置在一个 components/ 目录下,组件被 entry.js 引用,要使用 entry.js,我们把这个文件指定输出到 dist/bundle.js,Webpack 配置如下:
var path = require('path');
module.exports = {
entry: './entry.js',
output: {
path: path.join(__dirname, '/dist'),
filename: 'bundle.js'
},
resolve: {
extensions: ['', '.js', '.jsx']
},
module: {
loaders: [
{ test: /\.js|jsx$/, loaders: ['babel'] }
]
}
}
resolve 指定可以被 import 的文件后缀。比如 Hello.jsx 这样的文件就可以直接用 import Hello from 'Hello' 引用。
loaders 指定 babel-loader 编译后缀名为 .js 或者 .jsx 的文件,这样你就可以在这两种类型的文件中自由使用 JSX 和 ES6 了。