react的特点
响应式UI
作为开发者,你只需编写你想要的是什么,React 自己会弄清楚该怎么做。当数据变化时,UI 会相应地发生改变。你无需再关心 DOM 的更新,React 会自动帮你完成。响应式 UI 的理念大大地简化了 UI 开发。
组件化
虚拟Dom
jsx
jsx其实就是javaScript对象
如果想要在html标签中使用js 需要把js用{}括起来
以下都是在index.js中实现 需要引入
import ReactDom from 'react-dom'
import React from 'react'
使用jsx的规范语法
超过一个标签时 必须使用一个根标签包裹
let ele = <h1>hello</h1><span>world</span>
//第一种使用一个标签包裹
let ele = <div><h1>hello</h1><span>world</span></div>
//第二种使用空标签 包裹
let ele = <><div><h1>hello</h1><span>world</span></div></>
//第三种 使用<React.Fragment></React.Fragment>包裹
let ele = <React.Fragment><h1>hello</h1><span>world</span></React.Fragment>
ReactDom.render(ele,document.getElementById('app'))
区分大小写
let ele = <Div>hello</Div> //'Div' is not defined react/jsx-no-undef
ReactDom.render(ele,document.getElementById('app'))
它的属性值必须用引号引起来
let ele = <h1 id=a1>hello</h1> //错误写法
let ele = <h1 id='a1'>hello</h1>
ReactDom.render(ele,document.getElementById('app'))
在jsx中不能直接使用class 应该使用className
let ele = <div class='myele'>hello</div> //错误写法
let ele = <div className='myele'>hello</div>
ReactDom.render(ele,document.getElementById('app'))
使用style的方式
let ele = <div style='color:red'>hello</div> //错误写法
let ele = <div style={{'color':'red'}}>hello</div>
ReactDom.render(ele,document.getElementById('app'))
jsx的所有标签都要闭合 包括单标签 双标签
let ele = <div><h1>hello</h1><img ></div> //错误写法
let ele = <div><h1>hello</h1><img /></div>
ReactDom.render(ele,document.getElementById('app'))
jsx中存放的数据类型
// jsx中可以放字面量
let ele = <div>123</div>
// jsx中可以放运算符 在jsx中 如果想要在html标签中放js 需要把js放到{}里面
let ele = <div>{1+1+1}</div>
//jsx可以放变量
let name = 'wangcai'
let ele = <div>{name}</div>
let ele = <div>{name +'xiaoqiang '}</div>
//jsx中可以放函数调用
let ele = <div>{Math.random()}</div>
//jsx中可以放jsx
let name = <strong>wangcai</strong>
let ele = <div>{name}</div>
// ReactDom.render(ele,document.getElementById('app'))
react中没有v-if
使用if else实现
let isLogin = false
let ele = ''
if(isLogin){
ele = <strong>登陆成功</strong>
}
else{
ele = <strong>登陆失败</strong>
}
ReactDom.render(ele,document.getElementById('app'))
使用三元运算符实现
let isLogin = false
let ele = isLogin ? '登陆成功' : '登陆失败'
ReactDom.render(ele,document.getElementById('app'))
react中没有v-for
使用map实现
let name = ['vue.js','react.js',"angular.js"]
let ele = <div><ul>{name.map((item,index)=><li key={index}>{item}</li>)}</ul></div>
ReactDom.render(ele,document.getElementById('app'))
react 都是组件化
React 是围绕可重用组件的概念设计的。你定义小组件并将它们组合在一起形成更大的组件。
无论大小,所有组件都是可重用的,甚至在不同的项目中也是如此。 组件分为有状态组件 和 无状态组件 区分就是组件内是否有state
有状态组件
有状态组件中的数据分为两种 一种是自己内部的state(放到constructor中),通过this.state.xxx进行访问,它可以改变state中的状态(使用setState进行改变),但是其他的组件不可以改变状态,另一种是从上一层接受的数据(使用this.props.xxx),不可以改变数据,如果想要使其改变,只能让父组件重新赋值
使用类组件进行写的话 里面必须有一个render钩子函数 这个钩子函数必须return
在App.js
import React,{Component} from 'react'
class App extends Component{
constructor(props){
super(props)
this.state={
name:'wangcai'
}
}
render(){
return(
<>
<div>{this.state.name}</div>
<button onClick={this.updateName.bind(this}>修改name</button>
<p>{this.props.age}</p>
</>
)
}
updateName(){
this.setState({
name:'xiaoqiang'
})
}
}
无状态组件
无状态组件其实就是使用函数形式写的组件,它的内部没有state,状态都是从上层获取到的,使用props.xxx进行获取,它不能调用this,没有生命周期也就是没有钩子函数里面必须return
在App.js
import React from 'react'
function App(props){
return(
<div>{props.name}</div>
)
}
在index.js
import React from 'react'
import ReactDom from 'react-dom'
import App from './App'
ReactDom.render(<App name='wangcai'></App>,document.getElementById('app'))
在index.html中
<div id='app'></div>
react中的方法
class App extends Component{
constructor(){
this.state={
name:'wangcai'
}
}
render(){
return(
//jsx 这里的this都是指向App组件
<div>{this.state.name}</div>
<button onClick={this.updateName}>修改name</button>
)
}
updateName(){
console.log(this)
//会输出undefined 因为只有在jsx中this是指向App这个组件
//所以需要手动的绑定this
}
}
给方法手动绑定this的方法
在构造器中(constructor)中进行绑定
constructor(){
this.state={
name:'wangcai'
}
this.updateName=this.updateName.bind(this)
}
在调用方法时进行绑定
<button onClick={this.updateName.bind(this)}>修改name</button>
在jsx中直接实现方法
<button onClick={console.log(this)}>修改name</button>
有状态的组件进行父传子
在App.js 父组件传子组件,不仅可以传数据,也可以传方法 它需要一级一级的往下传
import React,{Component} from 'react'
import Children from './Children'
//在父组件中引入子组件 不用注册 直接使用
//如果传值的话 在父组件中设置数据 在子组件中接受数据
// 导入一个组件在jsx中使用 vue中是在tempate中使用
// 每一个组件中都有一个state,react和vue一样,也可以使用props
// vue中 每一个组件中都一个data 数据源:data props
// props在vue主要是用来传递数据的,实现父子通信的,是父给子传递数据。
// react中props也是用来传递数据,实现通信的,也是父传子,可以传递数据,也可以传递方法
// 如何使用Props?
// 需要有父组件和子组件
// 在父中设置数据,在子中获取数据
// 子中通过this.props.属性名来获取数据
class App extends Component{
render(){
return(
<>
<h1>父组件</h1>
<Children></Children>
{/* <Children age={100}></Children> */}
{/* <Children age={'wangcai'}></Children> */}
</>
)
}
}
export default App
在Children.js中
可以对接受的数据进行验证 使用propoTypes验证 使用defaultProps进行默认值
import React,{Component} from 'react'
import PropTypes from 'prop-types'
// 子中接收到数据后,能改变数据吗?
// vue中可以改变,但是不推荐
// vue中数据源:data props data是每一个组件都有的,props是别人传递的数据
// props是别人传递的,人家不建议你去修改数据 如果你要经常修改数据,把数据定义到data中
// react中的数据源也是有两个:state props
// 尽量使用props 在react中获取数据推荐在上层组件中获取, 然后传递给子组件,子组件通过this.props接收实使用
class Children extends Component{
constructor(props){
super(props)
}
render(){
return(
<>
<p>子组件</p>
{/* 在子组件中直接使用this.props.age就可以接受父组件传入的数据 */}
<p>{this.props.age}</p>
</>
)
}
}
// 检验传入的数据是不是number类型的
Children.propTypes={
age:PropTypes.number
}
//不传入数据的时候 默认为111
Children.defaultProps = {
age:111
}
export default Children
无状态的父传子
import React from 'react'
import PropTypes from 'prop-types'
//传统的写法 下面是箭头函数形式
function App(props){
return(
<div>
<h1>无状态组件</h1>
<p>{props.name}</p>
</div>
)
}
const App = (props)=>{
return(
<div>
<h1>无状态组件</h1>
</div>
)
}
//上面的简化形式 把return和{}省略掉
const App = props =>(
<div>
<h1>无状态组件</h1>
{/* 无状态组件中没有this */}
{/* <p>{this.props.name}</p> */}
{/* 直接使用props.name */}
<p>{props.name}</p>
</div>
)
//检验传过来的数据
App.propTypes = {
name:PropTypes.string
}
//如果没有传过来数据 设置默认数据
App.defaultProps = {
name:'xxx'
}
export default App
// 无状态组件 就是函数形式的组件
// 有状态组件 就是class形式的组件
// 无状态组件指这个组件中没有state 数据源是props
// 传递的数据可以校验,propTypes
特点:
1,function 无状态组件不会被实例化,性能高
2,无状态组件不能访问this
3,无状态组件没有生命周期,也就是没有钩子函数
4,无状态组件数据源只能靠props
react建议,尽可能地使用无状态组件
state vs props ?
state是组件内部定义的数据 props是别人传递的数据
state在组件内部初始化,自身可以修改数据(this.setState),别人是不能修改,可以
把state当成局部的,只能被自身使用的数据源,当state改变了,那么会导致组件重新渲染
props主要是父传给子的数据 ,在react中子中是没有办法修改props接收过来的数据
如果要修改一个别人传递过来的一个props,只能再让别人重新传递过来一个新的Porps
尽可能少的使用state,尽可能多的使用props
根据state可以把组件分成两类:有状态组件(有state) 无状态组件(无state)
有状态组件通常使用class来定义
无状态组件通常使用function来定义