React 特点
1.声明式设计 −React采用声明方式,可以轻松描述应用。
2.高效 −React通过对DOM的模拟(虚拟DOM),最大限度地减少与DOM的交互。
3.灵活 −React可以与已知的库或框架很好地配合。
4.JSX − JSX 是 JavaScript 语法的扩展。React 开发不一定使用 JSX ,但我们建议使用它。(对比模板引擎)
5.组件 − 通过 React 构建组件,使得代码更加容易得到复用,能够很好的应用在大项目的开发中。
6.单向响应的数据流 − React 实现了单向响应的数据流,从而减少了重复代码,这也是它为什么比传统数据绑定更简单
一且皆为组件
函数化编程(Functional Programming)
它属于”结构化编程“的一种,主要思想是把运算过程尽量写成一系列嵌套的函数调用
1.纯函数(html) 输入一定输出也一定(只要不会改变原数组原对象就是纯函数)
2.柯理化函数(js)原来能多个参数,要求变成一个参数
function sum(a){
return function(b){
return function(c){
return a+b+c
}
}
}
sum(2)(3)(4) 9
高级写法
var fn = a=>b=>c+>a+b+c
fn(2)(3)(4) //9
好处:
1.代码简洁,开发快速
2.接近自然语言,易于理解
3.更方便的代码管理
4.易于“并发编程”
5.代码的热升级
2.基础
main.js
//引入react 可以在当前JS中使用JSX语法
import React from "react"
//操作DOM
import ReactDOM from "react-dom"
ReactDOM.render(
h1, //组件1
document.getElementById("app"), //2
()=>{ //3
console.log("挂载成功")
}
)
index.html中,需要一个大div <div id="app"></div>
参数:
1.需要渲染的DOM节点或者组件,如果渲染的是标签则只需要写标签名(如:h1)即可,如果是组件则需要按照标签的形式输写(如:<App/>)
2.需要将渲染的这个节点挂载在哪里
3.回调
渲染内容用{}
如:
相当于innerText
let message = "111";
let dom = <h2>{message}---{3>2?'大于':'小于'}----{1+1}</h2>; //输出:111--大于--2
相当于innerHtml
let h2 = <h2>React</h2>
let dom = <div>{h2}</div> //输出<h2>React</h2>
判断
相当于if
let flag = true;
let dom = <div>{flag?<h2>111</h2>:''}</div> //输出111
相当于if-else 只能用三目来判断
let n = 10;
let dom = <div>{n==1? <p>111</p>:n==2? <p>222</p>:<p>333</p>}</div>
相当于show显示隐藏
let flag = false;
let dom = <div><h2 style={{display:flag?"block":'none'}}>1902</h2></div>
绑定数据
相当于bind
let title="一个图片";
let style = {
width:"300px",
height:"300px",
background:'red'
}
let myclass = "box1 box2 box3"
let dom = <div title={title} style={style} className={myclass}>
<label htmlFor="">
111
</label>
</div>
jsx语法中class需要改写成className for需要改写成htmlFor
创建组件
1.通过class来创建一个组件
语法:class 组件名称 extends React.Component{}
class App extends React.Component{
render(){
return(
<div></div>
)
}
}
export default App //导出APP
render: 是一个生命周期 用来渲染JSX DOM节点(虚拟DOM的渲染)
语法:
render(){
return <div></div>
}
注意:必须要return出去一个节点 (只能返回一个节点类似与vue template里面只能有一个子元素)
如果需要返回多个元素的时候,只有一个根节点
简写,解构方式
import React,{Component} from "react"
export default class App extends Component{
render(){
return <div></div>
}
}
React.Component: 是所有组件的父类
组件内部必须包含返回一个生命周期render,不写会报错
遍历
例:
//需要用括号
第一种方法
{
arr.map((item,index) =>{
return <p key={index}>{item}</p>
})
}
第二种方法
{
arr.map( (item,index) =>(<p key={index}>{item}</p>))
}
var fn = () =>{} 块级作用域不会自动返回 需要写return
var fn = () =>() 加框号返回整体 不需要写return
var fn = () =>({}) 加框号返回对象 不需要写return
组件中生命周期constrcutor中必须写super
constrcutor(){
super()
this.state ={
message= "1902"
}
}
this.state
表示:当前组件所需要的一些状态
语法:
<h2>{this.state.message}</h2> //1902
事件绑定 如:on
handleClick //自定义函数
bind(this) //表示指向当前组件
<button onClick={this.handleClick.bind(this)}></button>
handleClick(){
this.state.message = "1903"
}
因为是单向数据流,所以数据不会改变
想要改变数据要用 this.setState
handleClick(){
this.setState({
massage:1903
})
}
数据修改 this.setState
1.react中如何修改this.state中的数据
2.this.setState是同步的还是异步的
-------异步的
3.this.setState的第二个参数的作用
4.this.setState为什么是异步的
语法
this.setState({
key:val
},()=>{})
key:需要改变状态的属性
val:需要改变成的值
第二种方法
this.setState(()=>({
message:val
}),()=>{})
this.setState的第二个参数( (中有state)=>{} )的作用:
1、查看数据是否修改成功
2、获取数据更新后的DOM结构
(中有state)=>{} 写上state可以对数据进行检测
只要this.setState被调用那么render函数就会被执行
render 执行说明DOM重新加载一次
this.state 这个函数只能它之内修改,之后不能修改,想要修改
强制更新数据
this.forceUpdate(); //底层原理手动调用render函数
双数据绑定----多用在表单
重复的东西可以做解构
如: let {message} = this.state
<input type="text" value={message} onChange = { this.handleChange.bind(this)}/> 不能传参
<p>{message}</p>
value和onChange一起使用,单个会警告
React中value 与 defaultValue区别
1、value属于html的属性 value会使输入框变成一个受控组件
2、defaultValue属于DOM的属性 defaultValue会使输入框变成一个非受控组件
受控组件--表示不能写入
非受控组件---表示能写入
性能优化
事件收写的方式
1、this.函数名称.bind(this)
2、this.函数名称 性能最好
3、onClick = {()=>{ }} 回调整不推荐
this.handleChange = this.handleChange.bind(this)
handleChange(e){
var val = e.target.value;
this.setState({
message:val
})
}
表单
export default class App extends Component{
constructor(){
super();
//存放当前组件所需要的一些状态
this.state = {
message:"1902",
radioVal:"男",
checkBoxVal:[],
selectedVal:"1902"
}
this.handleChange = this.handleChange.bind(this)
this.handleRadio = this.handleRadio.bind(this)
this.handleCheckBox = this.handleCheckBox.bind(this)
this.handleSelected = this.handleSelected.bind(this)
}
render(){
let {message,radioVal,checkBoxVal,selectedVal} = this.state;
return(
<div>
{/*<input type="text" value={message} onChange = {this.handleChange.bind(this)}/>*/}
<input type="text" value={message} onChange = { this.handleChange}/>
{/*<input type="text" value={message} onChange = { ()=>{*/}
{/*this.setState({*/}
{/*message:123*/}
{/*})*/}
{/*}}/>*/}
<p>{message}</p>
<hr/>
<label>
男 <input type="radio" value="男" checked={radioVal == '男'} onChange={ this.handleRadio}/>
</label>
<label>
女 <input type="radio" value="女" checked={radioVal == '女'} onChange={ this.handleRadio}/>
</label>
<p>您选择的性别是:{radioVal}</p>
<hr/>
<label>
抽烟 <input type="checkbox" value="抽烟" onChange={ this.handleCheckBox}/>
</label>
<label>
喝酒 <input type="checkbox" value="喝酒" onChange={ this.handleCheckBox}/>
</label>
<label>
烫头 <input type="checkbox" value="烫头" onChange={ this.handleCheckBox}/>
</label>
<label>
大保健 <input type="checkbox" value="大保健" onChange={ this.handleCheckBox}/>
</label>
<ul>
您的爱好有:
{
checkBoxVal.map((item,index)=>(
<li key={index}>{item}</li>
))
}
</ul>
<hr/>
<select value={selectedVal} onChange={this.handleSelected}>
<option value="1902">1902</option>
<option value="1903">1903</option>
<option value="1904">1904</option>
<option value="1905">1905</option>
<option value="1906">1906</option>
</select>
<p>您选择的班级是:{selectedVal}</p>
</div>
)
}
handleChange(e){
var val = e.target.value;
this.setState({
message:val
})
}
handleRadio(e){
var val = e.target.value;
this.setState({
radioVal:val
})
}
handleCheckBox(e){
let val = e.target.value;
let arr = this.state.checkBoxVal;
//判断数据是否在数组中存在
let flag = arr.includes(val);
if(flag){
let index = arr.indexOf(val);
arr.splice(index,1);
}else{
arr.push(val);
}
this.setState({
checkBoxVal:arr
})
}
handleSelected(e){
let val = e.target.value;
this.setState({
selectedVal:val
})
}
}