react是什么?
react是Facebook开发出的一款JS库
react特点:
- react 不适用模板
- react 不是一个MVC框架
- react 响应式(数据更新的时候非常简单)
- reacr 是一个轻量级的js库
react原理:
- 虚拟Dom react当中把dom抽象成一个js对象,通过这个js对象实时更新真实的Dom,操作虚拟Dom的速度远远大于操作真实Dom,这样就提升了我们操作Dom的性能
- diff算法 当页面数据发生变化 先更新虚拟Dom 而不去更新真实Dom 跟新js对象的速度远远大于更新真实Dom,react会先把虚拟Dom进行渲染,渲染成功后再统一的对真实Dom进行渲染
react 安装:
- 下载react核心包 npm i react --save
- 下载react-dom npm i react-dom --save
- 下载babel npm i babel-standalone --save
下面是初识react的案例讲解和介绍,看完你算是就react入门了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./node_modules/react/umd/react.development.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<script src="./node_modules/babel-standalone/babel.min.js"></script>
<script src="./node_modules/prop-types/prop-types.js"></script>
<style>
.a{
text-decoration: none;
}
</style>
</head>
<body>
<div id="demoReact"></div>
<div id="demoReact1"></div>
<div id="demoReact2"></div>
<div id="demoReact3"></div>
<div id="demoReact4"></div>
<div id="demoReact5"></div>
<div id="demoReact6"></div>
<div id="demoReact7"></div>
<div id="demoReact8"></div>
<div id="demoReact9"></div>
<div id="demoReact10"></div>
<div id="demoReact11"></div>
<div id="demoReact12"></div>
<div id="demoReact13"></div>
<div id="demoReact14"></div>
<div id="demoReact15"></div>
<div id="demoReact16"></div>
<div id="demoReact17"></div>
</body>
<script type="text/babel">
// 1.渲染dom节点内容注释方法 {/*注释内容*/}
let MyDom = <div>
{/*我是需要注释的内容*/}
内容1
</div>;
ReactDOM.render(MyDom,document.getElementById("demoReact"));
// 注意: 多行标签需要有一个父元素包裹
// 2.多行标签
let MyDom1 = <div>
<div>内容1</div>
<div>内容2</div>
</div>;
// 插入页面dom节点
ReactDOM.render(MyDom1,document.getElementById("demoReact1"));
// 在jsx中插入javascript表达式
// 注意:如果想要在jsx中使用表达式 那么我们就需要把表达式放入一对{}中
// 1.使用表达式计算 三目运算符
let text = "价格";
let num = 9527;
let MyDom2 = <div>
<div>{text}:{num == 9527?num+1:num+2}</div>
</div>;
ReactDOM.render(MyDom2,document.getElementById("demoReact2"));
// 2.表达式中调用函数
let user={
name:"小明",
age:22
}
let MyDom3 = <div>
<div>{fun(user)}</div>
</div>;
function fun(obj){
return `姓名是${obj.name}-------年龄是${obj.age}`;
}
ReactDOM.render(MyDom3,document.getElementById("demoReact3"));
// 3.渲染数组
let arr = [
<p>新闻标题1</p>,
<p>新闻标题2</p>,
<p>新闻标题3</p>,
]
let MyDom4 = (
<div>
{arr}
</div>
)
ReactDOM.render(MyDom4,document.getElementById("demoReact4"));
// 注意: 在jsx中不能使用class 因为class是js的关键字 jsx语法为className
// 4.设置html标签属性
let msg = "点我去百度";
let linkUrl = "http://www.baidu.com";
let aStyle = {color:"red"};
let MyDom5 = <a className="a" style={aStyle} href={linkUrl}>{msg}</a>;
ReactDOM.render(MyDom5,document.getElementById("demoReact5"));
// 5.react列表渲染 map()
let life = ["吃饭","睡觉","玩游戏"];
// map遍历
let MyDom6 = life.map((item,index)=>{
// 必须设置key值
// 注意:不能换行 如果需要换行用()把内容包裹起来
/**
* 示例:
* return (
* <h3 key={index}>{item}</h3>)
* */
return <h3 key={index}>{item}</h3>;
})
// for in 循环遍历
// let MyDom6 = [];
// for(let index in life){
// MyDom6.push(<h3 key={index}>{life[index]}</h3>)
// }
// 传统for循环类似...举一反三
ReactDOM.render(MyDom6,document.getElementById("demoReact6"));
// 6.遍历对象
let userInfo = [
{name:"小明",age:18},
{name:"张三",age:19},
{name:"李四",age:20},
{name:"王二",age:21}
]
let MyDom7 = userInfo.map((item,index)=>{
return <h3 key={index}>姓名:{item.name},年龄:{item.age}</h3>;
})
ReactDOM.render(MyDom7,document.getElementById("demoReact7"));
// 7.面向组件编程
// 组件到底是什么?
// 高耦合、低内聚 高耦合就是把逻辑紧密的内容放在一个组件中 低内聚就是把不同组件之间的依赖关系尽量弱化 每个组件尽可能的独立起来
// 组件当中的重要内容
// 1.构建方式
// 2.组件的属性
// 3.生命周期
// 演变过程 传统组件有几个明显的特点
// 1.简单的封装 2.简单的生命周期的呈现 3.明显的数据流动
// 当一个项目比较复杂的时候 传统的组件根本不能很好地把结构和行为结合让项目很难维护
// react的组件分为3个部分 1.属性 props 2.状态 state 3.生命周期
// react的组件是一个非常重要的概念 通过组件可以把页面中的ui部分切分成 独立 高复用性的部件 让每个开发者专注于一个个独立的部件
// 组件与组件化
// 组件 就是用实现页面局部功能的代码几个 简化页面的复杂程度 提高运行效率
// 组件化 当前程序都是使用组件完成的 那么就是一个组件化的应用
// 组件的创建
// 函数组件/无状态组件
// 无状态组件的创建方式 注意:方法名首字母大写
function MyCom(){
return (
<div>我是一个无状态组件</div>
)
}
// 组件嵌套
function MyCom1(){
return (
<div>
<MyCom/>
<MyCom/>
</div>
)
}
// 组件就是自定义的标签
// 调用组件
let MyDom8 = <MyCom1/>;
ReactDOM.render(MyDom8,document.getElementById("demoReact8"));
// 创建类组件
// class MyCom2 extends React.Component{
// render(){
// return (
// <div>我是一个类组件</div>
// )
// }
// }
// let MyDom8 = <MyCom2/>;
// ReactDOM.render(MyDom8,document.getElementById("demoReact8"));
// props是react中一个重要的属性 是组件对外的接口 我们使用props就可以从组件外部向组件内部传递数据,也就是父组件向子组件传递数据
// 注意: 无论是无状态组件还是类组件 我们都不能修改自身的props
function Com(props){
return (
<div>我是一个无状态组件---外部传递的数据是:{props.text}</div>
)
}
//Com组件数据默认值
Com.defaultProps={
text:"我是默认值"
};
// let ComTent = "我是传递给Com的props数据";
// let MyDom9 = <Com text={ComTent}/>;
let MyDom9 = <Com/>; //默认值调用 类组件同上
ReactDOM.render(MyDom9,document.getElementById("demoReact9"));
// 类组件传递数据
class Com1 extends React.Component{
render(){
return (
<div>我是类组件---外部传递的数据是:{this.props.text}</div>
)
}
}
// 8.props验证 --- 验证传递进来的数据是否符合我们期望的类型或者要求 上线模式中请取消props
// 1.引用prop-types库 npm install --save prop-types
Com1.propTypes={
text:PropTypes.number.isRequired //验证text这个props传递进来的数据必须是number类型,而且不能为空
}
let ComTent1 = 123;
let MyDom10 = <Com1 text={ComTent1}/>;
ReactDOM.render(MyDom10,document.getElementById("demoReact10"));
// 9.state 状态
// state和props的区别
// props是组件对外的接口 state是组件对内的接口
// 组件内可以引用其他组件 组件之间的引用就形成了一个树状的接口 如果子组件需要使用父组件的数据
// 父组件就可以通过子组件中props来进行数据的传递 因此props就是组件对外的接口
// 组件除了使用父组件传递的数据之外 他自身也可能有需要管理的数据 这个对内管理数据的属性就是state
// 主要区别:
// 1.state是可变的
// 2.props对于当前页面的组件来说 他是只读 如果我们想修改props中的数据 那么我们修改传递给当前组件数据的父组件中的内容
// react中我们只需要关心的是数据 当数据改变的时候页面就会自动的发生改变
// 状态等同于页面中的数据 状态/数据改变了---页面中对应的数据绑定内容就会被react自动的进行改变
// 声明式渲染 --- 一切的数据改变操作都不用我们关心 只需要我们申明好数据 react就会自动的对于数据进行相应的改变
// 注意:如果想使用state状态 那么不能使用无状态组件
class Header extends React.Component{
// 在ES6中不管子类写不写constructor 在new实例的时候都会有默认的constructor
// 如果写了constructor就必须写super() super就是指向父类构造方法
constructor(props){
// 如果想在constructor使用props 那么super中必须写上props
super(props)
// 定义state
this.state={
name:"姓名:"
}
}
render(){
return (
<div>
{/*改变state数据语法 this.setState({key:newValue}) 异步的 react就会自动的出发render渲染*/}
<button onClick={()=>{this.setState({name:this.state.name+"张三"})}}>点我改变state数据</button>
<div>我是state的数据{this.state.name}</div>
</div>
)
}
}
let MyDom11 = <Header/>;
ReactDOM.render(MyDom11,document.getElementById("demoReact11"));
// 10.转发 refs react当中提供了一个ref的数据 (不能在无状态组件当中来进行使用 因为无状态组件没有实例)
// 表示当前组件的真正实例的引用 它会返回绑定的当前属性的元素
// 标识组件内部的元素---方便我们查找
// react给我提供了三种方式进行ref的使用
// 1.字符串的方式
// 2.回调函数(推荐) 就是在dom节点上或者组件上挂载函数 函数的入参是dom节点 达到的效果和字符串方式是一样的
// 3.React.createRef() react16.3新提供的一种方式 把值赋给一个变量 通过ref挂载在节点或者组件上 使用ref的current属性拿到这个节点
// 注意:官方建议我们不要过度的使用refs对逻辑进行处理 需要优先考虑state
class Nav extends React.Component{
constructor(props){
super(props);
this.myRef = React.createRef();
}
func=()=>{
// console.log(this.refs.demoInput.value);
// console.log(this.textinput.value);
console.log(this.myRef.current.value);
}
render(){
return(
// 字符串方式
// <div>
// <input type="text" ref="demoInput" placeholder="请输入"/>
// <button onClick={this.func}>点我得到输入框的值</button>
// </div>
// 函数调用
// <div>
// <input type="text" ref={(input)=>{this.textinput=input}} placeholder="请输入"/>
// <button onClick={this.func}>点我得到输入框的值</button>
// </div>
// React.createRef()
<div>
<input type="text" ref={this.myRef} placeholder="请输入"/>
<button onClick={this.func}>点我得到输入框的值</button>
</div>
)
}
}
let MyDom12 = <Nav/>;
ReactDOM.render(MyDom12,document.getElementById("demoReact12"));
// 11.react事件处理 react绑定事件使用的是小驼峰命名法 在绑定函数的时候不能加() --->函数会立即执行
// 1.bind方式原定绑定
// 2.函数通过箭头函数进行创建
// 3.consternation中的提前绑定
// 4.把时间的调用携程箭头函数的调用方式
class Bind extends React.Component{
constructor(props){
super(props);
this.func = this.func.bind(this);
}
funa(){
console.log(this);
}
funb=()=>{
console.log(this);
}
func(){
console.log(this);
}
fund(){
console.log(this);
}
fune(i,e){
console.log(i);
console.log(e);
}
render(){
return (
// bind方式原定绑定
// <div>
// <button onClick={this.funa.bind(this)}>bind方式绑定</button>
// </div>
// 函数通过箭头函数进行创建
// <div>
// <button onClick={this.funb}>函数通过箭头函数进行创建</button>
// </div>
// constructor中的提前绑定
// <div>
// <button onClick={this.func}>constructor中的提前绑定</button>
// </div>
// 把时间的调用携程箭头函数的调用方式
// <div>
// <button onClick={()=>{this.fund()}}>把时间的调用携程箭头函数的调用方式</button>
// </div>
<div>
<h1>函数传参实战</h1>
<button onClick={this.fune.bind(this,"参数1")}>bind方式</button>
<button onClick={()=>{this.fune("参数2")}}>箭头函数方式</button>
<h1>事件传参</h1>
<button onClick={(e)=>{this.fune("参数3",event)}}>箭头函数方式</button>
</div>
)
}
}
let MyDom13 = <Bind/>;
ReactDOM.render(MyDom13,document.getElementById("demoReact13"));
// 12.状态提升 多个子组件需要使用相同的state数据,提升到他们最近的一个父组件中,多个子组件需要利用到对方状态情况下
class DemoA extends React.Component{
constructor(props){
super(props);
}
funa(value){
this.props.funa(value);
}
render(){
return(
<div>
我是第1个子组件---{this.props.text}
<button onClick={this.props.news.getChildData.bind(this,'我是子组件1的数据')}>点我修改</button>
</div>
)
}
}
class DemoB extends React.Component{
constructor(props){
super(props);
}
funa(value){
this.props.funa(value);
}
render(){
return(
<div>
我是第2个子组件---{this.props.text}
<button onClick={this.props.news.getChildData.bind(this,'我是子组件2的数据')}>点我修改</button>
</div>
)
}
}
class Main extends React.Component{
constructor(props){
super(props);
this.state={
commontext:"我是两个组件都想使用的数据"
}
}
getChildData=(res)=>{
this.setState({commontext:res})
}
render(){
return(
<div>
我是父组件
<button onClick={this.getChildData.bind(this,"我是父组件的数据")}>点我修改</button>
<DemoA news={this} text={this.state.commontext}/>
<DemoB news={this} text={this.state.commontext}/>
</div>
)
}
}
// DemoA和DemoB需要使用同一个state状态
let MyDom14 = <Main/>;
ReactDOM.render(MyDom14,document.getElementById("demoReact14"));
</script>
</html>
react 脚手架安装
create-react-app 是Facebook官方提出的一款react的脚手架
安装环境:需要提前安装node 升级到最新版本
安装步骤:
- 全局安装脚手架环境 npm i -g create-react-app
- 查看脚手架是否安装成功 create-react-app --version
- 这样就安装成功了
- 创建项目 create-react-app 项目名