从0到1无比流畅的React入门教程
Posted 糖~豆豆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从0到1无比流畅的React入门教程相关的知识,希望对你有一定的参考价值。
无比流畅的React入门教程
React 是什么
简介
- 用于构建 Web 和原生交互界面的库
- React 用组件创建用户界面
- 通俗来讲:是一个将数据渲染为HTML视图的开源JS库
其他信息
- Facebook 开发,并且开源
为什么使用React?
- 原生JS使用DOM-API修改UI代码很繁琐,效率低下,React可以解决这种问题
- 原生JS直接操作DOM,浏览器会大量重绘重排,React可以解决这种问题
- 原生JS没有组件化方案好用,代码复用率很低,
- React 采用组件化模式,React 让你可以通过组件来构建用户界面
- React 使用声明式编码
- React 使用虚拟DOM,将数据映射成虚拟DOM,再生成真实DOM,当数据变化的时候,会对原有的虚拟DOM和新的虚拟DOM进行比较,再生成真实DOM。
- React 使用DOM diffing 算法,最小化页面重绘
特点
声明式设计 −为你应用的每一个状态设计简洁的视图,当数据改变时 React 能有效地更新并正确地渲染组件。
● 高效 −React采用Virtual DOM(虚拟DOM), 极大的提升了UI渲染(更新)效率。
● 灵活 −React 允许你结合其他框架或库一起使用。
● JSX − JSX 是 JavaScript 语法的扩展。JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。
● 组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
● 单向响应的数据流 − React 采用了单向响应的数据流,使组件状态更容易维护, 组件模块化更易于快速开发。
怎么用 React?
前置条件
- ES6
- Class
- js基础
文档
● 中文文档: https://zh-hans.reactjs.org
● 英文文档: https://reactjs.org
● React DevTools: https://github.com/facebook/react-devtools
● react CDN link: https://zh-hans.reactjs.org/docs/cdn-links.html
● babel CDN link: https://www.babeljs.cn/setup#installation
基础知识-点击获取教程代码
了解 Babel
- ES6转化为ES5
- JSX转化为JS
了解 jsx
JSX简介
1、全称:JavaScript XML
2、react定义的一种类似于XML的JS扩展语法:JS + XML本质是React.createElement(component, props, ...children)方法的语法糖
3、作用:用来简化创建虚拟DOM
4、写法:var ele =
Hello JSX!
基本语法规则
1、定义虚拟DOM时,不要写引号;
2、标签中混入JS表达式时要用;
3、样式的类名指定不要用class,要用className;
4、内联样式,要用style=key:value的形式去写;
5、只有一个根标签;
6、标签必须闭合;
7、标签首字母:
(1)小写字母开头,代表该标签转为html中同名元素
(2)大写字母开头,代表组件
开始上手
了解 模块与组件
模块
1、理解:向外提供特定功能的js文件;
2、业务逻辑增加,代码越来越多且复杂,需要拆成模块
3、作用:复用js,简化js的编写,提高js运行效率;
1、理解:用来实现局部功能效果的代码和资源的集合(html/css/js/image等等);
2、为什么要用组件: 一个界面的功能更复杂,拆分成一个一个小组件,更容易复用
3、作用:复用编码,简化项目编码,提高运行效率;
模块化、组件化
应用的js都以模块来编写-就是模块化
应用是以多组件的方式实现-就是组件化
React开发者工具
引入依赖库,理解基础jsx语法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<!-- React 核心库、 -->
<script src="lib/react/react.development.js"></script>
<!-- 操作 DOM 的 react 扩展库、 -->
<script src="lib/react/react-dom.development.js"></script>
<!-- 将 jsx 转为 js 的 babel 库 -->
<script src="lib/babel.min.js"></script>
</head>
<body>
<!-- 创建react解析的容器 -->
<div id="xiaojin"></div>
<script type="text/babel">
var msg = "I am xiaojin!!!";
//1.创建虚拟DOM
const VDOM = (
/* 此处一定不要写引号,因为不是字符串 */
<h1 id="title">
<span>Hello,msg</span>
</h1>
);
//2.渲染虚拟DOM到页面
ReactDOM.render(VDOM, document.getElementById("xiaojin"));
</script>
</body>
</html>
注释-在花括号里
ReactDOM.render(
<div>
/*注释...*/
</div>,
document.getElementById(\'XXX\')
);
数组-JSX 允许在模板中插入数组,且自动展开
var arr = [
<h1>A</h1>,
<h1>B</h1>,
];
ReactDOM.render(
<div>arr</div>,
document.getElementById(\'XXX\')
);
组件
- react提供两种形式创建组件,函数式组件和class形式
组件使用注意事项:
组件名必须是首字母大写
虚拟DOM元素只能有一个根元素
虚拟DOM元素必须有结束标签
< />
函数式组件
// 创建函数,返回一个虚拟DOM
function Test(props)
return <h1>Hello, props.name</h1>;
// 渲染
ReactDOM.Render(<Test name = "xiaojin" />,document.getElementById("div"));
class形式,这个提一下,后面就不再举例啦,之后都用函数式
<div id="root"></div>
<script type="text/babel">
var msg = \'hello,world!\';
// class形式
class HelloWorld extends React.Component
render()
console.log(\'this\',this);
return (
<div>msg</div>
)
ReactDOM.render(<HelloWorld />,document.getElementById(\'root\'));
组件核心属性
state
通俗理解:state就是组件的一些数据绑定,数据变了,页面就会变,这是我的理解哦
注意事项
1、切勿直接修改state数据,直接state会重新渲染内容;
2、通过setState修改后,不会立即修改DOM,react会在所有状态改变后,对比虚拟DOM,统一修改,提升性能;
关于this
- 组件中的 render 方法中的 this 为组件实例对象
- 组件自定义方法中由于开启了严格模式,this 指向
undefined
如何解决- 通过 bind 改变 this 指向
- 推荐采用箭头函数,箭头函数的
this
指向
因为类式组件基本不怎么用,所以接下来只写函数式组件内容啦
props
理解
1、每个组件对象都会有props(properties的简写)属性;
2、组件属性保存在props中;
作用
1、通过标签属性从外向组件内传递变化的数据;
2、props只读
使用:
<script type="text/babel">
function Person(props)
const name, age, sex = propsreturn(
<ul>
<li>姓名:name</li>
<li>性别:sex</li>
<li>年龄:age</li>
</ul>
);
Person.propTypes =
name: PropTypes.string.isRequired,
// 限制name必传,且为字符串sex:PropTypes.string, 限制sex为字符串age:PropTypes.number, 限制age为数值
;
// 标签属性值
Person.defaultProps =
sex: "女",
age: 18,
;
ReactDOM.render(<Person name="XIAOJIN" />, document.getElementById("root"));
</script>
refs
组件内的标签可以定义ref属性来标识自己
有三种操作refs
的方法,分别为:
- 字符串形式
- 回调形式 render()return(<input ref=c => this.input1 = c type="text" /> 箭头函数简写,使用时可通过
this.input1
来使用 createRef
形式
createRef step1:给DOM元素添加ref属性
<input ref=this.MyRef type="text" placeholder="点击弹出" />
<input ref=this.MyRef1 type="text" placeholder="点击弹出" />
createRef step2:通过API,创建React的容器,会将DOM元素赋值给实例对象的名称为容器的属性的current
MyRef = React.createRef();
MyRef1 = React.createRef();
// 调用
btnOnClick = () =>
// 创建之后,将自身节点,传入current中
console.log(this.MyRef.current.value);
事件处理
-
React 使用自定义事件,非原生 DOM 事件
-
React 事件通过事件委托方式处理(更高效)
-
可用
event.target
获取 DOM 减少refs
使用
非受控租价与受控组件
包含表单元素的组件分为非受控租价与受控组件
- 受控组件:表单组件的输入组件随着输入并将内容存储到状态中(随时更新)
- 非受控组件:表单组件的输入组件的内容在有需求的时候才存储到状态中(即用即取)
受控组件
1、表单元素依赖于状态,表单元素需要默认值实时映射到状态的时候,就是受控组件,这个和双向绑定相似;
2、元素修改实时映射状态值,可对输入内容进行校验;
3、只有继承React.Component才有状态;
4、必须使用onChange绑定
非受控组件
1、在虚拟DOM节点上声明ref,且将引用赋值ref
2、react会自动将输入的值放在实例的ref属性上
注意:官方推荐受控组件,更好的控制组件生命流程
1、受控组件的两个要点:
组件的value属性与React中的状态绑定
组件内声明了onChange事件处理value的变化
2、非受控组件更像是传统的HTML表单元素,数据存储在DOM中,而不是组件内部,获取数据的方式是通过ref引用;
3、尽可能使用受控组件;
4、受控组件是将状态交由React处理,可以是任何元素,不局限于表单元素;
5、大量表单元素的页面,使用受控组件会使程序变得繁琐难控,此时使用非受控组件更为明智;
生命周期 LifeCycle
React 生命周期主要包括三个阶段:初始化阶段,更新阶段,销毁阶段
初始化阶段
1. constructor 执行
constructor
在组件初始化的时候只会执行一次
通常它用于做这两件事
- 初始化函数内部
state
- 绑定函数
2. static getDerivedStateFromProps 执行
getDerivedStateFromProps
在初始化和更新中都会被调用,并且在 render
方法之前调用,它返回一个对象用来更新 state
getDerivedStateFromProps
是类上直接绑定的静态(static
)方法,它接收两个参数 props
和 state
props
是即将要替代 state
的值,而 state
是当前未替代前的值
3. componentWillMount 执行(即将废弃)
如果存在
getDerivedStateFromProps
和getSnapshotBeforeUpdate
就不会执行生命周期componentWillMount
。
3. render 执行
render()
方法是组件中必须实现的方法,用于渲染 DOM ,但是它不会真正的操作 DOM,它的作用是把需要的东西返回出去。
实现渲染 DOM 操作的是 ReactDOM.render()
注意:避免在
render
中使用setState
,会造成死循环
4. componentDidMount 执行
componentDidMount
的执行意味着初始化挂载操作已经基本完成,它主要用于组件挂载完成后做某些操作
这个挂载完成指的是:组件插入 DOM tree
总结
执行顺序 constructor
-> getDerivedStateFromProps
或者 componentWillMount
-> render
-> componentDidMount
继续补充中---
今天就写到这里啦~
- 小伙伴们,( ̄ω ̄( ̄ω ̄〃 ( ̄ω ̄〃)ゝ我们明天再见啦~~
- 大家要天天开心哦
欢迎大家指出文章需要改正之处~
学无止境,合作共赢
欢迎路过的小哥哥小姐姐们提出更好的意见哇~~
React从入门到放弃之前奏:React简介
本系列将尽可能使用ES6(ES2015)语法。所以均在上节webpack的基础上做开发。
React是Facebook开发的一款JS库,因为基于Virtual DOM,所以响应速度快,以及支持跨平台。
(实际上,Virtual DOM在某些情况都会损耗一些性能在diff上,但相比其他MVVM框架比起来性能影响很少,同时大幅提升开发效率也是目前推荐的方式)
安装
安装React: npm i -S react react-dom
安装Babel:npm i babel-loader babel-preset-react babel-plugin-import -S
HelloWorld
import React from 'react';
import ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello, world!</h1>,
document.getElementById('root')
);
JSX
JavaScript 的一种扩展语法。我们推荐在 React 中使用这种语法来描述 UI 信息。
- JSX支持嵌入表达式:花括号 把任意的 JavaScript 表达式 嵌入到 JSX 中
- JSX是Javascript:比起 HTML, JSX 更接近于 JavaScript, React DOM 使用驼峰(camelCase)属性命名约定。(html为全小写)
- JSX防注入攻击:在渲染之前, React DOM 会格式化(escapes) JSX中的所有值。防止 XSS(跨站脚本) 攻击。
- JSX编译后为: React.createElement()。
const element = (
<h1 className="greeting">
Hello, world!
</h1>
);
const element = React.createElement(
'h1',
{ className: 'greeting' },
'Hello, world!'
);
// 注意: 以下示例是简化过的(不代表在 React 源码中是这样)
const element = {
type: 'h1',
props: {
className: 'greeting',
children: 'Hello, world'
}
};
组件
React框架的一大特色就是它通过组件化的方式来构建和渲染前端页面。
定义组件有很多方式,最主流的为:函数 和 类(类允许我们在其中添加本地状态(state)和生命周期钩子。)
function Welcome(props) {
return <h1>Hello, {props.name}</h1>;
}
class Welcome extends React.Component {
render() {
return <h1>Hello, {this.props.name}</h1>;
}
}
Props
- 属性是只读的:无论你用函数或类的方法来声明组件, 它都无法修改其自身 props。
- 属性是外部控制的:属性是由外部设置,组件内部是不确定属性从哪设置的。
- 稳定性:对于同样的输入,始终可以得到相同的结果。
State
- state是内部控制的:state是私有的,并且由组件本身完全控制。
- 使用setState修改:
- 内部调用render
- 支持异步
- 支持更新合并state
生命周期事件
React组件的生命周期事件很多,常用的有:
- componentDidMount:在组件第一次初始化render方法后调用,此时组件(DOM及诶点)已创建完成。通常在此方法中ajax、使用第三方js框架。
- shouldComponentUpdate:在组件接收到新的state或props后被调用。(第一次初始化和forceUpdate时不被调用。 )默认返回true,返回false的时候则不调用render方法。
- componentWillUnmount:在组件从DOM中移除的时候被调用。通常用来移除组件相关事件。
生命周期事件又分为3条流程:
- 组件初始化(Mounting):getDefaultProps、getInitialState、componentWillMount、render、componentDidMount(getInitialState在ES6 class的构造函数中可直接对state初始化)
- 组件props更新(Updating):componentWillReceiveProps(nextProps)、shouldComponentUpdate、componentWillUpdate、render componentDidUpdate
- 组件卸载(Unmounting):componentWillUnmount
表单
受控组件
React负责渲染表单的组件仍然控制用户后续输入时所发生的变化。相应的,其值由React控制的输入表单元素称为“受控组件”。
class ShowInput extends Component {
constructor(props) {
super(props);
this.state = {
val: 'hello'
}
}
onChange(e) {
this.setState({
val: e.target.value
})
}
render() {
return (
<div>
<input type="text" onChange={e => this.onChange(e)} />
<div>{this.state.val}</div>
</div>
)
}
}
DivInput组件中的input元素就是受控组件。value 和 onChnage都会由React控制。
非受控组件
render() {
return (
<div>
<input type="text" ref={e => this.input = e} />
<button onClick={() => console.log(this.input.value)}>Click</button>
</div>
);
}
挂到组件(这里组件指的是有状态组件)上的ref表示对组件实例的引用,而挂载到dom元素上时表示具体的dom元素节点。(stateless构造的组件是不会实例化,所以ref引用的为null)
ref属性可以设置为一个回调函数,这也是官方强烈推荐的用法;这个函数执行的时机为:
- 组件被挂载后:回调函数被立即执行,回调函数的参数为该组件的具体实例。
- 组件被卸载或者原有的ref属性本身发生变化时:回调也会被立即执行,此时回调函数参数为null,以确保内存泄露。
ReactDOM.findDOMNode(ref)来获取组件挂载后真正的dom节点。
组件通信
组件之间通信的解决方案通常有2种:
- 状态提升:将state提升到互相通信组件的最近的一个父组件上
- Redux:下节将介绍
以上是关于从0到1无比流畅的React入门教程的主要内容,如果未能解决你的问题,请参考以下文章
react从0到0(再尼玛学不会自己就去吃屎吧(我不是针对看到这篇文章的人,我只针对自己))