React的初步
介绍
-
react是有facebook公司的前端开发团队进行开发和维护的一套js库
-
react一切皆组件,all in JS
-
react是用来构建web用户交互界面
-
react提供一套虚拟DOM(virtual dom),机制
-
react中facebook专为其提供一套语法糖---jsx
优点:
-
一切皆组件,在react中几乎全是使用组件进行开发
-
速度快,react提供了虚拟dom机制,
-
跨浏览器兼容,甚至在IE8中也可以使用
-
单向数据流,适合开发复杂的项目,出了问题容易溯源
缺点
-
react本身不是一套完整的框架,react需要结合flux和redux等架构来实现完整的项目
-
react最多只能算mvc中的view
react解决的痛点
-
组件化: 在react中一切组件组件
-
开发效率:react中使用组件化思想,使代码变得易于读懂和开发
-
运行效率:react采用的是虚拟dom机制,相比于原生开发效率速度更高
-
可维护:react中使用组件来构建大型项目,使得一些复杂的项目变得易于维护,.
-
在用户体验方面:react采用SPA(单页面应用),使得用户体验更好.
下载安装
-
方式一
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
-
方式二
npm i create-react-app -g 全局安装工具链 create-react-app -V 查看版本 create-react-app 项目名称 创建项目 cd xxx 进入项目目录 npm start 开启项目 // 修改默认端口号 node_modules/react-scripts/scripts/start.js const DEFAULT_PORT = parseInt(process.env.PORT, 10) || 5000; 或者 `"start": "set port=5000 && react-scripts start"`
项目目录介绍
my-app -node_modules #项目的依赖包 -public #公共资源文件 index.html #项目唯一的一个页面 -src #项目目录 App.css #根组件的样式 App.js #根组件 App.test.js #根组件的测试文件 index.css #唯一的入口文件的样式 index.js #唯一的入口文件 .gitignore #上传到Git上忽略的内容 package-lock.json #安装node_modules 中的依赖包的锁定版本 package.json #安装node_modules中相关的依赖项 READ.me #项目解读文件
JSX语法:JSX是对js的扩充,允许js和html混写
-
遇到 <>,JSX 就解析成 HTML;遇到 {}按 JavaScript 解析。
-
虚拟 DOM 只允许有一个根节点
-
JSX 标签可以相互嵌套注意换行和缩进,增强代码的可读性
-
建议使用小括号括将 JSX 代码括起来 ,防止分号自动插入的 bug
-
通过 JSX 语法将数据绑定到虚拟 DOM 对象(是一个js的object),再通过 render 将数据渲染到真实 DOM
修改标签内容
内容可以有简单的运算,类似vue的文本插值
修改标签属性
<img src={imgUrl} alt="" /> <a href={url}>中公教育</a> {/* 在jsx的语法中,html的类名class要写成className,js中的class还写成class */} <div className={className1}>修改我的class</div> {/* 在jsx的语法中,style的类型需要是对象,所以需要两个花括号。多个单词的属性名要写成:fontSize */} <div style={{ color: 'red', fontSize: '40px' }}>修改我的style</div>
条件渲染
<div>条件渲染:简单的用三元表达式写,复杂的用if...else</div> <div> { (function () { if (hasWude) { return (<p>666</p>) } else { return (<p>555</p>) } })() } </div>
循环渲染
<div>循环渲染,类似vue的v-for。使用map方法实现</div> <ul> { list.map(item => { return (<li key={item.name}>{item.name}---{item.age}</li>) }) } </ul>
组件
函数组件和类组件的区别:1.比较熟悉function,不熟悉class,class功能更强大,function性能更好;2.class可以有this;3.class有生命周期钩子,函数组件没有;4.state的处理。函数组件适用于简单的静态页面展示。
事件绑定
-
两种绑定方式
<button onClick={(e) => this.showData('ES6', e)}>ES6-箭头函数</button> {/* 默认this是undefined,需要通过bind(this)绑定 */} <button onClick={this.showData.bind(this, 'ES5')}>ES5-普通函数</button> {/* <button onClick={this.showData}>ES5-普通函数</button> */}
-
传递参数
{/* this指向当前组件,参数在e前面 */} <button onClick={(e) => this.showData('ES6', e)}>ES6-箭头函数</button> {/* 默认this是undefined,需要通过bind(this)绑定,参数在this后面 */} <button onClick={this.showData.bind(this, 'ES5')}>ES5-普通函数</button> {/* <button onClick={this.showData}>ES5-普通函数</button> */}
-
事件对象
传递事件对象e之后,可以获取e相关的信息,例如e.target.value等
-
阻止默认事件
e.preventDefault(); (写return false不行)
-
阻止冒泡
e.stopPropagation()
-
改为捕获的方式
加上Capture这个关键字,例如:onClickCapture={(e)=>this.clickHandler1('big',e)}
state 状态机:管理数据状态,可以初始化数据,类似vue中的data
-
初始化
this.state = { age: 18, money: 1000, msg: '' }
-
获取状态:this.state.xxx
-
修改状态,这是一个异步的方式,想要获取最新的值,可以在回调函数中获取
this.setState({ money: this.state.money + 100 }, ()=> { console.log(this.state.money); })
props的使用
在组件中通过this.props.xx获取,如果想在构造函数中使用props,需要传入参数
constructor(props){ // 调用super之后,才可以使用this super(props); // state:状态机。管理数据状态,可以初始化数据,类似vue中的data this.state = { age: 18, val: this.props.val // 使用props中的值进行初始化 } } render() { console.log(this.props); // 在其他函数中可以通过解构赋值获取 const {age,name} = this.props return ( <div className="alert alert-info" > <h1>用户信息</h1> <div>name的值为:{name}</div> <div>age的值为:{age}</div> </div> ) }
通过props实现组件传值:
-
父传子:通过组件的属性传递
// 在父组件中 <ComC info={this.state.msg} info2="2" ></ComC> // 在子组件中 render(props) { return ( <div> <mark>{this.state.msg}</mark> {/* 子组件通过this.props接受父组件的数据 */} <h1>{this.props.info}</h1> <h1>{JSON.stringify(this.props)}</h1> {/* 子组件触发父组件的函数,并在参数的位置传入数据,传给父组件 */} </div> ) }
子组件不能修改父组件传过来的值,read only property,这是只读属性 2. 子传父
// 父组件传给子组件的函数,函数中包含了获取数据之后的操作 fn(data) { this.setState({ childMsg: data }) } // 在父组件中,先向子组件传递一个函数 <ComC fn={this.fn.bind(this)} ></ComC> // 在子组件中调用传过来的函数,函数的参数就是子传父的数据 <button onClick={(e)=>this.props.fn(this.state.msg,e)}>子传父</button>
state和props的区别:
-
state: 是组件内部的状态数据,state的数据不能直接修改,如果需要修改需要通过特殊方法setState()进行修改.
-
props:一般用于组件之间通信,并且通常是父组件向子组件传递数据,通过this.props来接收.this.props的数据不能直接修改,如果需要修改,则需要通过父组件中的setState来进行修改.