前端知识点回顾——Reactjs
React.js
编写react需要安装的三个开发环境下的模块
- babel 解析JSX
- react 实现ui用户界面
- react-dom 处理dom
JSX:在JavaScript里面写html代码(最好用圆括号包起来,单标签要闭合),在html代码中用插值符号{}可以写js代码
ReactDOM.render(element, container, cb) 往容器中渲染一个组件element
循环返回dom的时候要加上key属性,但这个属性不能在props中取到
添加css用style属性=一个对象,属性名用驼峰形式命名。
事件名字用驼峰形式命名,其最后一个参数才是事件对象event。
Object.keys(obj)
可以通过扩展运算符+对象给一个标签添加属性:{...data[item]}
声明式无状态组件
function Main(props){ //大写名字的函数,返回一个组件
return (
<div>{props.con}</div>
)
}
let element = (
<div>
<Main con={'simple'}/>
</div>
);
声明式有状态组件
定义一个类继承React.Component,在render方法中返回要渲染的HTML元素。
class Head extends React.Component {
constructor(props){
super(props) // 执行父类的构造函数
this.name = 'dream'
this.age = 18
}
// 不要写function
say(){
console.log('say方法')
}
render(){ // 渲染
return (
<header> 这是真正的有状态的组件 头部 </header>
)
}
}
将在原型上的事件触发函数指向this的三个方法
在标签的事件属性中使用bind;
<header onClick={this.handleClick.bind(this,'argument')}></header>
在constructor中改变函数的this指向,但这种就不适合传参;
this.handleClick = this.handleclick.bind(this)
在原型上定义该函数的时候使用箭头函数;
handleClick = (e)=>{}
//传参的时候使用箭头函数
<header onClick={(e)=>{this.handleClick('arguments',e)}}></header>
包含关系
组件的子元素会被存到props.children属性中:
function FancyBorder(props){
return (
<div className={'FancyBorder FancyBorder-' + props.color}>
{props.children}
</div>
);
}
function WelcomeDialog(){
return (
<FancyBorder color='blue'>
<h1>Welcome</h1>
<p>Thank you for visiting my blog!</p>
</FancyBorder>
)
}
虽然不太常见,但有时你可能需要在组件中有多个入口,这种情况下你可以使用自己约定的属性而不是 children:
function SplitPane(props){
return (
<div>
<div>
{props.left}
</div>
<div>
{props.right}
</div>
</div>
)
}
function App(){
return (
<SplitPane
left={<Contacts />}
right={<Chat />}
/>
);
}
属性和组合为你提供了以清晰和安全的方式自定义组件的样式和行为所需的所有灵活性。请记住,组件可以接受任意元素,包括基本数据类型、React 元素或函数。
关键字
class -> className
value -> defaultValue
for -> htmlFor
focus -> autoFocus
操作DOM的方式
常规的获取DOM方法:id,类名等
通过事件对象,在该元素身上绑定的事件函数中获取; event.target
通过ref属性,在旧版本中通过给标签ref属性一个字符串,然后实例对象中的ref对象是由保存以ref属性为键,对应的节点为值的键值对组成
<input ref={'btn'}/> //this.refs.btn就指向这个节点
在新版本中建议在ref属性中使用回调函数,在回调函数中给实例对象定义一个值,将该节点直接赋给该值:
<div ref={itemDiv=>this._div=itemDiv}></div> //this._div就指向这个节点
findDOMNode 参数是dom节点时返回dom节点,参数是组件时返回组件渲染的dom节点
子组件往父组件通讯的方法
把父组件的方法通过props传递给子组件,在子组件中调用并传参,就会传到父组件的方法中
生命周期函数
生命周期:组件从定义到挂载,最后渲染到页面的一个过程。
第一阶段:挂载阶段
constructor 构造函数
只会在定义组件的时候执行一次,在此阶段可用于初始化state状态。
componentWillMount()
在组件即将被挂载的时候调用一次,此时组件还没有被渲染出来,这个时候不能够进行DOM操作。此时可以请求接收后端的数据。
render()
渲染组件。
componentDidMount()
此阶段组件挂载完成,用户能够在页面上看到数据,可以对DOM进行操作。若组件包含子组件,则在子组件渲染完毕(constructor->cDM)后才会触发这个函数。
第二阶段:更新阶段(子组件)
(子组件的)构造函数
componentWillReceiveProps(nextProps)
父组件的数据更新会触发子组件的这个函数执行,在这里可以处理父组件更新后,通过props传到子组件的数据,更新构造函数中对应的state值的数据。
shouldComponentUpdate(nextProps, nextState)
是否更新组件,是否触发重新渲染,函数必须有一个Boolean的返回值,true表示执行render函数重新渲染并继续执行后面的生命周期函数,false表示不重新渲染,也就不会再继续执行render和后面的生命周期函数。无论是父组件中this.state导致props数据发生变化还是子组件中的this.state数据发生变化都会触发,对应的参数(state触发的就对应nextState,props触发的就对应nextProps)就变成那个将会发生改变后的数据。
一定要加上判断!因为setState后改变了state的状态又会触发这个函数,以免进入无限循环。另外一方面通过判断数据是否发生变化,如果发生变化则返回true触发重新渲染,不发生变化则返回false避免不必要的重渲染行为。
关于这个钩子函数的重要性的一篇博文:https://www.cnblogs.com/penghuwan/p/6707254.html
componentWillUpdate(nextProps, nextState)
组件即将会被更新。
render()
渲染组件。
componentDidUpdate(prevProps, prevState)
组件渲染完成后执行。对应的参数(state触发的就对应nextState,props触发的就对应nextProps)为会发生改变前的数据。
componentWillUnmount()
关闭网页或者子组件被销毁(在父组件中被取消引用的时候,会先触发父组件的render方法)的时候会执行
thi.setState()除了接收变量改变state属性外,还可以用第二种形式接收一个函数
this.setState((prevState, props)=>{
//先前的状态作为第一个参数,此次更新被应用时的props作为第二个参数
})
})
总结setState操作会触发的生命周期函数顺序如下:
setState -> shouldComponentUpdate(返回true继续往下,返回false就在这里截止了) -> render -> 子组件的componentwillreceiveprops -> 子组件shouldcomponentupdate(返回true继续往下,返回false就在这里截止了) -> 子组件componentwillupdate -> 子组件 render -> 子组件componentdidupdate -> componentdidupdate
利用脚手架开发
安装: npm i create-react-app -g
创建:create-react-app appname
运行项目:npm start
表单控件
- 非受控(非约束性)表单控件:用户输入的表单的值value,react根本就不知道,例如常规的文本表单用户输入了什么react都不能实时得到,需要转成受控表单控件。
- 受控(约束性)表单控件:让react管理表单的数据,能够监视表单的一举一动。表单的value值改变则重新渲染(用自己的说法就是表单的初始状态是由state里决定,表单值value一旦改变state值也要随着进行更新,然后重新渲染表单)
//文本框
class Text extends React.Component{
state = {val : ''}
handleChange = (e)=>{
this.setState({val:e.target.value});
}
render(){
return (
<div>
<input type='text' value={this.state.val} onChange={this.handleChange}></input>
</div>
)
}
}
//单选框
class Radio extends React.Component{
state = {
sex: 'male';
}
handleChange = (e)=>{
this.setState({sex: e.target.value});
}
render(){
return (
<div>
<input type='radio' name='sex' value='male' checked={this.state.sex === 'male'} onChange={this.handleChange}/>
<input type='radio' name='sex' value='female' checked={this.state.sex === 'female'} onChange={this.handleChange}/>
</div>
)
}
}
//下拉菜单
class Select extends React.Component{
state = {
cityList: ['GZ','SZ','SH'],
city:''
}
handleChange = (e)=>{
this.setState({city:e.target.value});
}
render(){
return (
<div>
<select name='city' value={this.state.city} onChange={this.handleChange}>
{
this.state.cityList > 0 &&
this.state.cityList.map((item,index)=>{
return (
<option key={index}>{item}</option>
)
})
}
</select>
</div>
)
}
}
//复选框
class Checkbox extends React.Component{
state = {
name: [{value:'a',checked:true},{value:'b',checked:false},{value:'c',checked:false}]
}
handleChange = (index,e)=>{
const arr = this.state.name;
arr[index].checked = !arr[index].checked;
this.setState({name:arr});
}
render(){
return (
this.state.name > 0 && this.state.name.map((item,index)=>{
return (
<input key={index} type='checkbox' checked={item.checked} onChange={this.handleChange.bind(this,index)}>{item.value}</input>
)
})
)
}
}
路由模块 react-router-dom
BrowserRouter 通常起名为Router, 是一个组件,可以让根组件挂载不同的其他组件
HashRouter 项目上线需要改为hashrouter,让后退操作可用
Route 根据路由控制不同的组件显示
<Route exact path='/' component={Home}></Route>
//exact表示严格匹配 path属性表示当前路由 component表示在当前路由下渲染Home组件
Link 控制路由跳转,相当于a标签
NavLink 功能和Link一样,但有更多api
<NavLink exact to={'/'} activeClassName='active'>首页</NavLink>
//exact严格匹配 to表示要跳转的路由 activeClassName表示标签在active状态下添加的类名
Switch 包裹Route,表示只匹配一个路由,渲染一个组件
Redirect 重定向,用于判断状态看是否需要进行重新定向,一旦渲染到页面上就重定向至指定路由。
<Redirect to='/'></Redirect>
在组件卸载之前 是可以更新状态的(setstate),在组件卸载之后 不要更新状态(setstate),会报错。
例如刚进入页面渲染组件时,过3秒它会更新state,如果在三秒内跳转到其他路由,也就是把这个组件给卸载的话就会出现报错信息。
这个时候可以通过设置componentWillUnmount,将this.setState函数设置为空。
this.props.match.path 得到匹配该子组件的路由
this.props.match.params.id 得到匹配该子组件的动态路由/:id
路由模块化
将路由的属性值保存于组件的state中或者是另起一个js文件保存导入,遍历然后展开(可以用扩展运算符…)
保存在state中:

用js模块导入:
//js模块
//直接导入组件
import News from '';
import Not404 from '';
import NewDetails from '';
const routes = [
{
exact: true, //要用到精确匹配则设置为true
path: '/',
component: Home
},
{
path: '/news',
component: News,
children: [ //子路由
{
exact: true,
path: '/news/',
component: NewIndex
},
...
]
},
...
{
path: '*',
component: Not404 //404模块放在最后
}
]
export default routes
//jsx
import routes form '';
import {Component} from 'react';
import {Switch,Route} from 'react-router-dom';
class App extends Compnent{
render(){
return (
<Switch>
{
routes.length>0 && routes.map((item,index)=>{
return <Route key={index} {...item} />
})
}
</Switch>
)
}
}
嵌套路由传参
如果像上面实现了路由模块化后,那么像News这个组件还有子路由children这个属性怎样去传递给它的子路由呢?答案就是我们不能简单地用component去指向路由要渲染的组件了,而是改用render方法。
还是以上面的routes路由模块数组举例
//jsx
import routes form '';
import {Component} from 'react';
import {Switch,Route} from 'react-router-dom';
class App extends Compnent{
render(){
return (
<Switch>
{
routes.length>0 && routes.map((item,index)=>{
return <Route key={index} path={item.path} render={props=><item.component {...props} routes={item.children}>}/>
})
}
</Switch>
)
}
}
这里用render方法替代component,直接表示返回组件,把子路由children通过routes属性传过去。另外要注意的是{...props}最好写上,这里包含了match等重要的属性,以便在组件中能够取到path和动态路由的值。
prop-types
可以引用内置模块prop-types设置父组件传过来的props属性的数据类型以及设置默认值:
import PropTypes from 'prop-types';
class Head extends Component{...}
//定义父组件中props属性的数据类型
Head.propTypes = {
data: PropTypes.array
}
//设置子组件的props默认的属性值
Head.defaultProps = {
simple: '子组件的默认值'
}
前端知识点回顾——Reactjs的更多相关文章
- 前端知识点回顾——HTML,CSS篇
前端知识点回顾篇--是我当初刚转行为了面试而将自己学过的前端知识整理成的一份笔记,个人目的性很强,仅供参考. doctype 有什么用 doctype是一种标准通用标记语言的文档类型声明,目的是告诉标 ...
- 前端知识点回顾之重点篇——ES6的Promise对象
Promise Promise 是异步编程的一种解决方案,比传统的解决方案--回调函数和事件--更合理和更强大. 所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异 ...
- 前端知识点回顾之重点篇——CSS中flex布局
flex布局 来源: http://www.ruanyifeng.com/blog/2015/07/flex-grammar.html?utm_source=tuicool 采用 Flex 布局的元素 ...
- 前端知识点回顾——mongodb和mongoose模块
mongodb和mongoose模块 数据库 数据库有关系型数据库(MySQL)和非关系型数据库(mongodb),两者的语法和数据存储形式不一样. mySQL 关系型数据库 类似于表格的形式,每一条 ...
- 前端知识点回顾——koa和模板引擎
koa 基于Node.js的web框架,koa1只兼容ES5,koa2兼容ES6及以后. const Koa = requier("koa"); const koa = new K ...
- 前端知识点回顾——Nodejs
Node.js 事件循环机制 setImmediate()是将事件插入到事件队列尾部,主线程和事件队列的函数执行完成之后立即执行setImmediate指定的回调函数,和setTimeout(fn,0 ...
- 前端知识点回顾之重点篇——jQuery实现的原理
jQuery jQuery的实现原理 参考:https://blog.csdn.net/zhouziyu2011/article/details/70256659 外层沙箱和命名空间$ 为了避免声明了 ...
- 前端知识点回顾——Javascript篇(六)
fetch 在原生ajax+es6promise的基础上封装的一个语法糖,返回promise对象. fetch(url, initObj) .then(res=>res.json()) .the ...
- 前端知识点回顾之重点篇——CORS
CORS(cross origin resource sharing)跨域资源共享 来源:http://www.ruanyifeng.com/blog/2016/04/cors.html 它允许浏览器 ...
随机推荐
- 如何让某些用户对Marketing Cloud的contact数据只能实施只读操作
打开maintain business role这个应用: 创建一个新的business role,然后添加下列这几个catalogs: SAP_CEC_BC_MKT_ADM_PC Marketing ...
- MVC方式显示数据(手动添加数据)
Model添加类 Customers using System; using System.Collections.Generic; using System.Linq; using System.W ...
- Nginx 优化详解
一.一般来说nginx 配置文件中对优化比较有作用的为以下几项: 1. worker_processes 8; nginx 进程数,建议按照cpu 数目来指定,一般为它的倍数 (如,2个四核的cpu计 ...
- 网页报警提示 This page includes a password or credit card input in a non-secure context. A warning has been added to the URL bar. For more information, see https://goo.gl/zmWq3m.
This page includes a password or credit card input in a non-secure context. A warning has been added ...
- Android Studio +git+jenkins+gitHub
之前做的jenkins+gitlab的jmeter,,,其实已经记不太清楚了. 最近又在搞Android学习,就试一下AndroidStudio+jenkins自动打包apk看看. step1: An ...
- Css案例整理
1.实现两个div并排显示 案例:checkbox的标题和内容需要并排显示,checkbox竖向排列 <head> <style type="text/css"& ...
- sqlserver常用运维sql
1. sqlserver 检测sql SELECT top 10 (total_elapsed_time / execution_count)/1000 N'平均时间ms' ,total_elapse ...
- [唐胡璐]Selenium技巧 - 定制元素属性检查,并写到ReportNG中
QTP 和Selenium 都会有这种要检查某一个控件元素属性的情况,比如去检查一个Button的显示文字是什么? 为了更方便的书写程序,并优美的显示到HTML测试报告中,做了以下几个小小的封装,只是 ...
- Greenplum实战之查询优化
本文主要分为三部分: GP优化需要准备的一些关于优化之外的知识,包括清空缓存.性能监控.执行计划分析. 具体优化措施,从以下四个方面考虑: 表.字段 sql GP配置.服务器配置 硬件及节点资源 GP ...
- 模块讲解---time模块,datetime模块,random模块,hashlib模块和hmac模块,typing模块,requests模块,re模块
目录 1. 包 2. time模块 1. 优先掌握 2. 了解 3. datetime模块 1. 优先掌握 4. random模块 1. 优先掌握 2. 了解 5. hashlib模块 ...