react基础
const element = ( <h1 className="greeting"> Hello, world! </h1> );
element经过babel转义成浏览器可识别的语法
const element = React.createElement( 'h1', {className: 'greeting'}, 'Hello, world!' );
虚拟DOM
const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world' } };
ReactDOM.render(element,document.querySelector('#root')); //把虚拟DOM render为真实DOM,插入到根节点
import React from 'react' import ReactDOM from 'react-dom'
给React元素增加属性时,属性名采用驼峰,只有两个关键字class和for要写成 className,htmlFor
style属性不能字符串,而是{{}}
{里写js代码,需要返回值,返回值不能是obj类型}
{['<li>1</li>','<li>2</li>']}会自动渲染成li元素集合,数组映射渲染如
{ this.state.pics.map((ele,i)=>{ return <img src={ele} key={i}/> }) }
组件的创建方式
1,函数式
function 组件名(props){
return <div>{props.}</div>
}
2,类的方式
class 组件名 extends React.Component{
constructor(props){
super(props);
this.state={}
}
render(){
return {this.props}
return <div>
<span></span>
</div>//如不写括号,则标签需和return有在一行,否则报错return nothing;//如写括号,则没限制
}
}
事件绑定
<普通元素 onClick={this.fn}>
1,绑定this的方法
1,onClick={this.fn.bind(this)} 2,在constructor(){ this.fn=this.fn.bind(this)
} 3,es7写法 fn=(event)=>{ this就是指向实例 }
2,给事件监听传参数
会自动给事件函数传递一个event参数
阻止默认事件使用event.preventDefault;return false会失效
1,onClick={this.fn.bind(this,参数1)} fn(对应参数1,event){} 2,onClick={(event)=>{this.fn(参数1,event)}}
state状态管理
this.setState(newObj,()=>{异步的回调函数})
框架内部执行Object.assign({},this.state.newObj) 并重新渲染render 多个setState会合并后在渲染 不是set一次渲染一次
this.setState((prevState)=>{//上一个状态 异步变同步 return {} })
组件通信
1,父传子: <组件 属性名=值>插入的标签</组件>
会将所有的属性名和值打包成一个对象,子组件通过props获取属性,通过props.children获取插入的标签,如果插入的标签是单个,则props.children是对象类型,如果是多个
那么是数组类型,解决办法:使用React.Children获取:React.Children.map(this.props.children,item=>item)
设置默认属性 组件名.defaultProps={}
import PropTypes from 'prop-types'
设置属性类型
组件名.propTypes={
属性名:PropTypes.string.isRequired
}
2,子传父:父组件传递函数属性,子组件调用函数
获取组件
ref={(参数)=>this.名字=参数}
参数就是指该DOM节点,通过this.名字就可以获取
生命周期
典型计数器
/** * Created by xueln on 2017/11/8. */ import React,{Component} from 'react' import ReactDOM from 'react-dom' class Counter extends Component{ static defaultProps={ name:'face' } constructor(){ super(); this.state={ num:0 } } componentWillMount(){ console.log('虚拟dom好了,将要挂载') } componentDidMount(){ console.log('组件挂载完成')
ajax请求数据,如果在willmount里会出现请求多次 } shouldComponentUpdate(newProps,newState){ console.log('组件是否需要更新') if(newState.num%2==0){ return true }else{ return false } } componentWillReceiveProps(){ console.log('组件将接受新属性') } componentWillUpdate(){ console.log('组件将要更新') } componentDidUpdate(){ console.log('更新完成') } add=()=>{ this.setState({ num:this.state.num+1 }) } render(){ console.log('挂载') return <div> 子组件 <hr/> { this.state.num<10?<Subcounter num={this.state.num}></Subcounter>:null } <p>{this.state.num}</p> <button onClick={this.add}>计数</button> </div> } } class Subcounter extends Component{ componentWillReceiveProps(){ console.log('子组件将接受新属性') } shouldComponentUpdate(newProps,newState){ console.log('子组件是否需要更新') if(newProps.num<8){ return true }else{ return false } } componentWillMount(){ console.log('虚拟dom好了,子组件将要挂载') } componentDidMount(){ console.log('子组件挂载完成') } componentWillUpdate(){ console.log('子组件将要更新') } componentWillUnmount(){ console.log('组件销毁') } componentDidUpdate(){ console.log('子组件更新完成') } render(){ console.log('子组件挂载') return <div> <p>{this.props.num}</p> <button ></button> </div> } } ReactDOM.render(<Counter/>,document.querySelector('#root'))