类组件
//rcc
class MyComponent extends React.Component {
render(){
return <h2>我是用类定义的组件</h2>
}
}
ReactDOM.render(<MyComponent/>,document.getElementById('test'))
- 类的方法在原型对象上,render()也不例外
- this指向组件实例对象
- ReactDOM.render:解析组件标签,发现是类,随后new出来该类的实例,并通过该实例调用原型对象的render方法,将虚拟DOM转为真实DOM
React.Component缺点
- 只要执行setState(),组件就会重新render() ==> 效率低
- 原因:React.Component中的shouldComponentUpdate()总是返回true
- 解决:
- 重写shouldComponentUpdate()方法,比较新旧state或props数据, 如果有变化才返回true, 如果没有返回false(麻烦)
- React.PureComponent
React.PureComponent
- PureComponent重写了shouldComponentUpdate(), 只有state或props数据有变化才返回true
state
state只能通过setState({})
方法修改
-
写在constructor里
constructor(props){ super(props) this.state={ name:"react" } }
-
写在constructor外(推荐)
state={ name:"react" }
setState
-
setState更新是对象合并(不是替换)
-
状态对象必须为新的对象
-
setState是同步的方法,但是状态为异步更新
- callback:在状态更新完毕,界面更新(render调用)后才被调用(类似vue.$nextTick() )
-
当有多个setState并排时,相同点是callback 在render后一起执行,不同点:
- 对象式不会累加,会覆盖
- 函数式可以连续累加
【写法】
-
对象式
- 参数一为状态对象,参数二为callback
this.setState({ num:this.state.num+1 },()=>{ console.log("在render之后获取最新的state:",this.state.num); })
-
函数式
- 参数一为函数,参数二为callback
- 函数的参数为当前的state和props,需要return一个状态对象
this.setState((state,props)=>{ return { num:state.num+1 } },()=>{ console.log("在render之后获取最新的state:",this.state.num); })
props
接收
-
通过
this.props
获取 -
setState
函数式也能获取到 -
函数式组件通过参数获取
function App(props) { console.log(props);//{a: '1', b: 2} return <></> }
-
constructor
中可以获取constructor(props){ super(props) console.log(this.props); }
-
<App>hello</App>
的hello也能接收到,属性名用children
接收
传递
单一传4=递
- 非字符串用
{}
- 还可以传递一个回调函数,类似“子传父”
<App a="1" b={2}/>
批量传递
-
使用拓展运算符
<App {...p}/>
拓展运算符不可以展开对象,必须使用 {} 包裹才行
babel和React结合可以让拓展运算符可以展开一个对象,方便传参,但只能用在组件的传参
refs
回调函数(常用)
- 参数为当前dom元素
<input ref={e=>this.input1=e} type="text"></input>
show=()=>{
console.log(this.input1.value);
}
【问题】
-
这种内联式写法,页面更新时执行一次
-
如果数据驱动页面更新,它会执行两次,第一次清空值为null,第二次获取Dom
【解决】
-
使用内绑定写法,单独定义”属性“方法,更新页面只会调用第一次
save = (e) => { this.input1 = e; console.log("@",e) } render() { return <> <input ref={this.save} type="text"></input> </> }
React.createRef()
input1=React.createRef()
<input ref={this.input1} type="text"></input>
show = () => {
console.log(this.input1.current);//Dom元素
}
- 被多次引用会覆盖