基础认识
- 官网
- 特点
- 声明式编程
- 组件化
- 支持客户端和服务端渲染
- 高效
- 虚拟DOM,不总是直接操作DOM,只是减少DOM的操作,操作虚拟DOM不会对页面进行重绘,当渲染的时候,才会进行渲染
- DOM Diff 算法,最小化页面重绘,就是当页面变化时,通过计算那部分需要重绘,只重绘当前部分,减少页面的重绘区域
- 单向数据流
- js文件
- react.js:react的核心库
- react-dom.js:提供操作DOM的react扩展
- babel.js:解析jsx语法
JSX
- react提供了创建虚拟DOM的方法
- 虚拟DOM对象最终都会被react转换为真实的DOM
- 编码时,只需要操作react的虚拟DOM相关数据,react会转换为真实DOM变化而更新界面
// react直接操作和JSX操作对比
- 动态渲染一个列表
- 使用数组的Map函数返回所需要的列表内容
let arrs = [111,222,333,444]
// 创建虚拟DOM
const ul = (
{
arrs.map((name,index) => - {name}
)
}
)
// 渲染虚拟DOM
ReactDOM.render(ul, document.getElementById('app1'))
组件
- 工厂函数创建组件
- 使用工厂函数的效率比使用class高,因为工厂函数中不需要创建一系列的对象之类的
- 当组件有状态(state)的时候就不适合使用了
// 工厂函数创建组件
function MyCom(){
return 工厂函数创建组件
}
// 渲染组件标签
// 必须这么写
// 这么写是错误的
ReactDOM.render( ,document.getElementById('app'))
- class创建组件
// class定义组件
class MyCom2 extends React.Component{
render(){
return class定义组件
}
}
// 渲染组件标签
// 必须这么写
// 这么写是错误的
ReactDOM.render( ,document.getElementById('app'))
组件三大属性
state
- state是组件对象的最重要的属性之一,值是一个对象,这个对象可以包含多个数据
组件被称为
状态机
,通过更新组件的state来更新对应的页面显示,就是通过state来控制组件的重新渲染(重绘)初始化状态
constructor(props){
super(props)
this.state = {
stateProp1:value1,
stateProp2:value2
}
}
- 读取某个状态值
this.state.statePropertyName
- 更新状态:组件重新渲染
this.setState({
stateProp1:newValue1,
stateProp2:newValue2
})
- 案例:点击切换内容
//定义组件
class Like extends React.Component{
constructor(props){
super(props)
//初始化状态state
this.state = {
isShow:false
}
//将新增方法中的this强制绑定为组件对象
this.handleClick = this.handleClick.bind(this)
}
// 新添加的方法:内置的this默认不是组件对象,是一个undefined
handleClick(){
//获取原始状态并取反
let isShow = !this.state.isShow
// 设置状态
this.setState({isShow})
}
// React.Component中本身就具有render函数,在class中只是重写组件类的方法render,所以这里的this指向没有问题
render(){
//获取状态
// const isShow = this.state.isShow
const {isShow} = this.state
//onClick是react的,区分原生的onclick
// this.handleClick.bind(this)也可以,但是这种效率比较低,因为每次render都会执行一次bind进行绑定,而在constructor中只会在初始化的时候绑定一次
return {isShow ? '我是帅哥' : '帅哥是我'}
}
}
//渲染组件
ReactDOM.render( ,document.getElementById('app'))
props
- 案例:定义一个显示个人信息的组件
- 姓名必须指定
- 性别默认为男
- 年龄默认为18
//创建组件
/* function Person(props) {
return (
- 姓名:{props.name}
- 性别:{props.sex}
- 年龄:{props.age}
)
} */
// class创建
class Person extends React.Component{
render(){
return (
- 姓名:{this.props.name}
- 性别:{this.props.sex}
- 年龄:{this.props.age}
)
}
}
//属性默认值
Person.defaultProps = {
sex:'man',
age:18
}
//属性的类型和必填
Person.propTypes = {
name:PropTypes.string.isRequired,
age:PropTypes.number
}
const p1 = {
name:'nordon',
sex:'man',
age:22
}
// 渲染组件
// ReactDOM.render( ,document.getElementById('app'))
ReactDOM.render( ,document.getElementById('app'))
const p2 = {
name:'lisan'
}
ReactDOM.render(,document.getElementById('app2'))
refs与事件处理
- 案例:获取input中的值
//定义组件
class MyInput extends React.Component {
constructor(props){
super(props)
this.handleClick = this.handleClick.bind(this)
this.handleBlur = this.handleBlur.bind(this)
}
handleClick(){
let input1 = this.refs.inputValue
console.log(input1.value)
console.log(this.newInput.value)
}
handleBlur(event){
console.log(event.target.value)
}
render (){
return (
this.newInput = inputValue } />
)
}
}
//渲染组件
ReactDOM.render( ,document.getElementById('app'))
ToDolist
- 简单的tdolist案例
// 定义组件
// 组件状态的更改必须在当前组件中进行
class App extends React.Component{
constructor(props){
super(props)
this.state = {
todos:['111','222','333']
}
this.addTodo = this.addTodo.bind(this)
}
addTodo(todo){
let {todos} = this.state
todos.unshift(todo)
this.setState({
todos
})
}
render(){
const {todos} = this.state
return (
this is todolist demo
)
}
}
class Add extends React.Component{
constructor(props){
super(props)
this.handleAdd = this.handleAdd.bind(this)
}
handleAdd(){
// console.log(this.refs.content.value);
//
// console.log(this.newTodos.value);
const data = this.newTodos.value
if(!data){
return false;
}
this.newTodos.value = ''
this.props.addTodo(data)
}
render(){
return (
this.newTodos = inputValue} />
)
}
}
Add.propTypes = {
count:PropTypes.number.isRequired,
addTodo:PropTypes.func.isRequired
}
class List extends React.Component{
render(){
let {todos} = this.props
return (
{todos.map( (item,index) => - {item}
)}
)
}
}
// name:PropTypes.string.isRequired,
List.propTypes = {
todos:PropTypes.array.isRequired
}
// 渲染组件
ReactDOM.render( ,document.getElementById('app'))