react.js笔记
这个要结合webpack笔记
目录
简介
- react.js是目前最流行的一门前端框架。
- React 是一个用于构建用户界面的 JavaScript库。
- React 主要用于构建UI,很多人认为 React 是 MVC 中的 V(视图)。
- React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 2013 年 5 月开源。
- React 拥有较高的性能,代码逻辑非常简单,越来越多的人已开始关注和使用它。
官方文档:https://reactjs.org/docs/getting-started.html
菜鸟教程:https://www.runoob.com/react/react-install.html
核心概念
DOM:dom是浏览器中的概念,即用来表示和操作页面上元素的JS对象。
虚拟DOM:在React中,表示用JS对象来模拟页面上的DOM和DOM嵌套,具有更高的性能。
Diff算法:即react中重新渲染dom表示的元素时,会对比新旧dom对象,然后只重新渲染发生了改变的元素。
key的作用:根据diff算法,key就是用来唯一标识每一个元素的,可以避免元素不必要的重新渲染,一般用在数组/列表映射或者同级元素移位中。
开始使用(旧版)
基本用法
搭建webpack环境
安装react:npm install react react-dom --save
;
react使用方式:
导入react:
import React from 'react'
import ReactDOM from 'react-dom'
创建元素:
/**
* 创建dom元素
* 参数1:创建的元素类型,如:h1、div、p、img等
* 参数2:dom元素的属性,可以为null,代表无属性
* 参数n:子节点
*/
const p1 = React.createElement('p', null, '这是p段落,在第一个div中')
const div1 = React.createElement('div', null, p1)
渲染元素:
/**
* 将虚拟元素渲染到页面
*/
ReactDOM.render(div1, document.getElementById('app'))
JSX语法支持
概念:js文件中默认不能写html标语语言,但是可以使用babel来转换为react的创建语句,这种在JS中混合写入HTML,符合xml规范的语法,叫做JSX语法,而webpack只支持原生js语法,所以需要在webpack中添加加载器loader,步骤如下:
使用babel-loader预编译jsx
语法:
使用文档:https://www.npmjs.com/package/babel-loader
- 安装babel以及相关依赖:
npm i babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/preset-react --D
- 依赖模块作用说明:
@babel/preset-env
:编译ES6@babel/preset-react
:转化JSX@babel/plugin-transform-runtime
:避免polyfill
污染全局变量,减小打包体积
- 在
webpack.config.js
文件中添加如下配置:
module: {
rules: [
// node_modules该目录下的文件不使用第三方插件打包
{
test: /(\.js|\.jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options:{
presets: [
'@babel/preset-env',
'@babel/preset-react'],
plugins: ['@babel/transform-runtime']
}
}
}
]
}
- 接着就可以在js文件中使用如下方式创建元素了
const div = <div id="div">这是一个div</div>
开始使用(新版)
官方文档:https://react.docschina.org/docs/hello-world.html
create-react-app官方文档:https://create-react-app.dev/docs/documentation-intro
create-react-app中文文档:https://www.html.cn/create-react-app/docs/getting-started/
方式一:
- 执行命令:
npx create-react-app app_name
- 进入app_name目录,执行启动命令:
npm run start
方式二:
npm install create-react-app --global
create-react-app app_name
- 进入app_name目录,执行启动命令:
npm run start
修改默认端口号:
- 找到文件:
/node_modules/react-scripts/scripts/start.js
- 修改端口号:
const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 80;
修改打包后的目录:
- 在
package.json
文件中添加配置:"homepage": "."
- 添加后的打包文件就可以直接用浏览器打开
html
文件访问了。
import与require
import:
- import是ES6语法,其最终会通过babel转换成CommonJS规范;
- 用
import
引入的组件需要export default导出; - react中推荐使用import
require:
- reuqire是CommonJs提出的规范;
- 用
require
引入的组件需要module.exports导出;
JSX语法
概念:在JS中混合写入HTML,符合xml规范的语法,叫做JSX语法。
多行注释:{/* 多行注释内容 */}
别名:jsx中,使用className
代替class
属性,使用htmlFor
代替label
标签的for
属性
style:在jsx中给标签设置style时,不能是字符串,而是对象,如:
const h1 = <h1 style={{color: 'red'}}>标题一</h1>
创建组件
方式一:
import React from 'react'
// 创建组件的第一种方式,规则如下:
// 1.方法名首字母要大写;
// 2.方法必须有返回值;
// 3.组件只能有一个顶层标签
// 3.props是通过<Hello name="val"></Hello>传入的
// 4.props也可以通过<Hello {...obj}></Hello>传入
// 5.props是只读的
export default function Hello(props){
var str = JSON.stringify(props)
return <div>这是hello, 属性对象:{str}</div>;
}
方式二(含state属性的用法):
import React from 'react'
// 创建组件的第二种方式,创建的规则同方式一
export default class Hello2 extends React.Component{
constructor(){
super()
// 有state表示有状态组件,没有state表示无状态组件,该属性相当于vue中的data
// 在渲染组件时若使用了state属性,则可以通过this.setState({})方法重新赋值和渲染相关组件
this.state = {msg: '私有属性'}
}
render(){
var str = JSON.stringify(this.props)
// 注意这里必须使用箭头函数
return <div onClick={() => this.modifyMsg()}>这是通过class创建的组件,包含传入属性:{str},私有属性:{this.state.msg}</div>
}
modifyMsg() {
// 此方法是异步方法,只会更新state里面的属性,不会覆盖
this.setState({msg: '私有属性被改了'})
}
}
使用组件
import React from 'react'
import ReactDOM from 'react-dom'
import Hello from './components/Hello'
ReactDOM.render(<Hello name="name_xxx" className='class_xxx'></Hello>,
document.getElementById('root'))
引用css
方式一(全局引用):
// 引入,全局有效
import './css/style.css'
// 使用
<div className='red b'>这是个具有class的div</div>
// 内联样式
<div style={{border: '1px solid #eee', padding: '5px'}}></div>
方式二(模块引入):
// 模块引入,只是在引入的js文件中有效
// 注意css的文件名必须以module.css结尾,这是新版用法
// 旧版还需要在webpack的配置文件中作相关配置
import MCss from './css/style.module.css'
// 使用
<div className={`${MCss.red} ${MCss.b}`}>这是个具有局部class的div</div>
绑定事件
// react中,点击事件的名称改为驼峰命名,值是函数对象,而不是字符串
// 另外:若该dom对象在类中,且需要使用类的成员方法作为事件函数时,需要使用箭头函数
<div onClick={function(){alert('xxx')}}>点击</div>
组件生命周期
获取后端数据
官网说明:http://react.html.cn/docs/faq-ajax.html
React 没有获取数据的具体方法,通常可以使用axios
或者jQuery AJAX
或者fetch()
API(兼容性不太好)来支持。
fetch使用文档:
https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch
https://www.html.cn/archives/9907
axios github文档:https://github.com/axios/axios
axios中文文档:http://www.axios-js.com/
路由
React中要实现页面间的跳转,常用的有react-router
和react-router-dom
两个包,下面以react-router
为例说明。
react-router中文文档:http://react-guide.github.io/react-router-cn/docs/Introduction.html
示例代码:
import React from 'react'
import { HashRouter as Router, Route, Link, Redirect, Switch } from 'react-router-dom'
function Header(props){
return <div>
<h1>路由组件</h1>
<Link to='/router/tab1/?id=1&name=张三'>页签一</Link>
<Link to='/router/tab2/2/李四'>页签二</Link>
<Link to={{pathname: '/router/tab3', query: {id: 1, name: '张三'}}}>页签三</Link>
</div>
}
function Tab(props){
var str = JSON.stringify(props)
console.log(props)
return <h3>页签内容,传入参数:{str}</h3>
}
export default class Index extends React.Component{
render(){
return <Router>
<Route path="/router">
<Header></Header>
<Switch>
<Route path="/router/tab1" component={Tab}/>
<Route path="/router/tab2/:id/:name" component={Tab}/>
<Route path="/router/tab3" component={Tab}/>
{/* Redirect必须在Switch内使用,且必须放在最后 */}
<Redirect from="/router" to="/router/tab1" exact></Redirect>
</Switch>
</Route>
</Router>
}
}
React-Redux
这块还不太理解,先简单记下;
简介
UI组件
- 只负责UI的呈现,不带有任何业务逻辑
- 没有状态(即不使用this.state这个变量)
- 所有数据都由参数提供(this.props)
- 不使用任何Redux的API
容器组件
- 负责管理数据和业务逻辑,不负责UI的呈现
- 带有内部状态
- 使用Redux的API
UI组件负责UI的呈现,容器组件负责管理数据和逻辑,如果组件既有UI又有业务,则将它拆分:外面是容器组件,里面包含了一个UI组件,前者负责与外部通讯并将数据传给后者,由后者渲染数据;
适用场景
- 当渲染一个组件的数据是通过props从父组件获取,形如:A -->B–>C–>D–>E–>F,此时F需要A的数据,同时还需要E–>A逆向回调,而中间的组件又不需要这些数据;
- 兄弟组件之间想要共享某些数据;
代码
参见demo代码笔记
node-sass安装失败的解决方法
npm i node-sass --registry=http://registry.npm.taobao.org