React
概念
- react是facebook出的一款针对view视图的library(库)。
使用
- 在使用react做项目的时候可以结合很多第三方的插件开发(路由插件,管理插件等等)。
- 浏览器只认识.js,.css.html文件,项目通过其他工具转化
- 使用jsx语法:在js文件中可以直接写html标签
1、组件定义:
//在html中
<div id='app'></div>
//在script标签中
//方法1、定义react组件
function HelloWorld()
{
return( //return返回的是要渲染的层次结构
<div>//唯一的根节点
<h3>第一个react样式</h3>
</div>
) }
//方法2、class定义组件
class Person extends React.Compoent{
constructor(props){
super(props)
//console.log(props['name'] //第一种子组件获取父组件的数据方式1
}
render(){
const {name}=this.props //第二种获取父组件数据方式,借助es6解构赋值
<div> //此处无法编写注释为了能够区分清楚两种方式不得已使用
// <h3>{this.props['name']}</h3> //第一种接收子组件数据渲染
<h3>{name}</h3> //第二种父组件数据渲染方式
</div>
}
}
//或者
const {Component} = React
class Child extends Component{
constructor(props)
{
super(props)
}
render(){
return(
<div>
<h3>类定义组件的另一种写法</h3>
</div>
)
}
}
function App extends Component{
constructor(props)
{
super(props)
}
render()
{
<div>
<h3>组件嵌套</h3>
<Person name="你好" />
<Child/>
</div>
}
} //将使用function定义的组件挂载到id为app上面 ReactDOM.render(<App/>,document.getElementById('app')))//第一个参数是组件名称,第二个参数表示组件挂载的位置
注意:
- class定义的组件有自己的局部状态和生命周期函数
- function没有局部状态,但是在react16.8之后的版本中新增了hooks函数,可以在function定义的组件中设置局部状态和模拟生命周期函数,用function定义的组件没有this指向的问题
2、组件传值
- 父传子:props属性
在嵌套组件的子组建内添加自定义属性,属性值是父组件要向子组件传递的数据,
子组件接收父组件数据的第一种方式:
(1)子组件通过构造函数的参数进行接收(props['name']),在子组件中直接用{this.props['属性名']}进行渲染,实际效果参考第一点代码
(2)子组件接收父组件传递数据的第二种方式:
子组件在render函数中借助es6的解构赋值,const {name}=this.props,接收父组件传递的数据,在return中直接{name}进行渲染实际效果也可以参考第一点的代码。 //{}在react中代表的是js代码书写
- 子传父:方法调用
过程描述:在子组件内,将要传递的数据作为父组件函数的实参,这里的函数是经过处理的函数(也就是将父组件的函数作为子组件的属性值,并且将父组件的this指向保留)
在子组件中: <button onClick={()=>props.toParsent("123","1233")}>点我</button>
在父组件App中: 首先定义一个函数 tap(a,b){//形参来接收来自子组件的数据 console.log('父组件数据') console.log(a,b) }
在子组件Son标签上 <Son toParsent={this.tap.bind(this)} />
3、循环
过程描述:首先定义一个数组 const people=[ {id:1,name:'你好'}, {id:2,name:'hello'}, {id:3,name:'fine'}, {id:4,name:'thanks'}, ]
在return里面直接用{}包裹写js代码即可 { people.map((ele,index)=>(<h3 key={ele.id}>{ele.name}</h3>)) }
return内的层次结构有且只有一个根节点
注意:当函数返回值渲染多个层次结构时,key值要写在根节点上面,另外函数方法需要有返回值;
循环{数组.map()}方法需要有返回值,map方法的返回值形成了一个新的数组,组件渲染出来的就是新数组
4、事件
在class定义的组件内声明函数tab tab(){ console.log(111) }
在该组件的render层次结构中添加事件 <button onClick={this.tab.bind(this)}>点击我</button>
5、state
- 作用:可以通过this.state为class定义的组件创建全局状态
过程描述:
在构造函数中定义变量 this.state={ count:1 }
在该组件中可以通过this.state直接获取组件的局部状态数据
通过this.setState可以修改当前的状态数据,修改之后会重新执行render进行页面的渲染
在该组件中通过变量解构赋值,const {count}=this.state获取状态数据count的值,之后在render的结构中{count}渲染出来
可以为count局部状态数据的改变添加一个点击事件,在事件中通过this.setState对局部状态数据进行修改 this.setState({count:this.state.count+1},function(){console.log('改变了')})
之后在render中将数据count渲染出来 {count}
注意:setState是异步执行的,它可以接收两个参数,参数1表示需要改变状态的数据,第二个参数表示状态改变之后的处理函数
6、数据双向绑定
利用setState修改局部状态数据
输入框数据双向绑定
过程描述:在构造函数中声明局部状态变量 this.state={ count:1 }
在render中引入 const {count} =this.state
在return层次结构中加入input表单元素 <input type="text" onKeyUp={event=>{this.setState({count:event.target.value})}}
也可以将this.setState通过函数封装起来,通过调用事件来实现布局状态数据的改变
注意:keyup事件与keydown的区别——keydown获取数据时获取不到当前输入的值
7、样式定义
- 在react中定义样式时使用className代替class
- style指定样式的时候需要使用一个对象作为参数,样式名字需要使用驼峰命名方式
样式设置描述:在组件的render中 return( <div> <H3 className="main">这是一个h3标题</h3> </div> )
在style标签中 <style> .main{ color:red; } </style>
8、数据交互——axios
使用过程描述:
引入axios文件
声明一个数据用来存储json数据 this.state={ list:[] }
在react生命周期函数componentDidMount(组件创建成功之后执行的生命周期函数)
componentDidMount(){ axios.get('url').then(res=>{ this.setState({ list=res }) }) }
在render中解构赋值得到list数组 const {list}=this.state
在return中遍历数组进行渲染,注意遍历数组的方法需要有返回值所以不能使用向forEach等的方法 {list.map((ele,index)=> (
{list.pname}
) )}