React
一、首先是React的核心概念 React的核心概念大概就是两个,一个是虚拟DOM另一个是diff算法。正式因为有了这两个核心概念,使得React的性能大大的提升。 首先虚拟DOM: 虚拟DOM就是对于DOM的抽象,虚拟DOM就是一个对象,用这个对象来描述DOM,每次通过对比DOM的变化差异,而选择对变化的部分重新渲染,并不是直接的在DOM上进行操作,从而提升的渲染的效率。 接下来是diff算法: 在某一时刻调用render()函数渲染了一棵元素树,在下一次state或者props更新时,又会生成一棵元素树,而diff算法就是对比这两棵树的差异点,从而只改变变化的部分。 对于根节点元素类型不同时,会拆掉原有的树并且会建一棵新的树。就相当于拆卸掉原有树上的所有节点然后重建。拆卸时会触发componentWillUnmount()函数,而重建会触发新建流程,从componentWillMount()函数,紧接着是componentDidMount()函数。 对于同一类型的元素,React 会保留 DOM 节点,仅比对及更新有改变的属性。 对于同类型组件元素,组件更新时,对于state不变,而props改变时调用componentWillReceiveProps()函数和componentWillUpdate()函数对元素进行改变。 对于在子节点后面添加节点,react会匹配旧结点,然后完成新节点的插入 对于在子节点前面插入节点,React会提供key属性,用key属性来匹配旧结点,对于有key属性的节点仅仅移动位置,对于新的节点再添加。 二、React的使用 首先导入react;然后创建DOM;接着渲染。 // 1. 导入 react import React from ‘react‘ import ReactDOM from ‘react-dom‘ // 2. 创建 虚拟DOM // 参数1:元素名称 参数2:元素属性对象(null表示无) 参数3:当前元素的子元素string||createElement() 的返回值 const divVD = React.createElement(‘div‘,{ title: ‘hello react‘ },‘Hello React!!!‘) // 3. 渲染 // 参数1:虚拟dom对象 参数2:dom对象表示渲染到哪个元素内 参数3:回调函数 ReactDOM.render(divVD,document.getElementById(‘app‘)) 三、React创建组件两种方式 第一种通过函数来创建,通过JS函数来创建,也叫无状态组件,这种创建仅仅是为了展示数据,不需要对于数据进行改变。 function Welcome(props) { return ( <h1>Hello {props.name}</h1> ) } ReactDOM.render( <Welcome name="jack" />,document.getElementById(‘app‘) ) 第二种通过class来创建,也叫有状态组件,可以操作数据而不是简单的展示数据。 class Clock extends React.Component { render() { return ( <div> <h1>Hello,world!</h1> <h2>现在是 {this.props.date.toLocaleTimeString()}.</h2> </div> ); } } function tick() { ReactDOM.render( <Clock date={new Date()} />,document.getElementById(‘example‘) ); } 四、props和state props:用于父子组件中传递数据,只读不可修改添加,props.children获取组件的内容。 function Welcome(props) { // 返回的 react元素中必须只有一个根元素 return <div>hello,{props.name}</div> } class Welcome extends React.Component { constructor(props) { super(props) } render() { return <h1>Hello,{this.props.name}</h1> } } state:数据,用于组件内部数据传递,也叫状态,只有class创建才有state,sate是私有的,由组件来控制。 class Hello extends React.Component { constructor() { // es6继承必须用super调用父类的constructor super() this.state = { gender: ‘male‘ } } render() { return ( <div>性别:{ this.state.gender }</div> ) } } 五、组件生命周期 1、创建:constructor() 、componentWillMount() 、render() 、componentDidMount() 2、运行交互:componentWillReceiveProps() 、shouldComponentUpdate() 、componentWillUpdate() 、render() 、componentDidUpdate() 3、卸载:componentWillUnmount() 创建阶段:该阶段函数只执行一次。 constructor():获取props、设置state。 class Greeting extends React.Component { constructor(props) { // 获取 props super(props) // 初始化 state this.state = { count: props.initCount } } } // 初始化 props // 语法:通过静态属性 defaultProps 来初始化props Greeting.defaultProps = { initCount: 0 }; componentWillMount() :
componentWillMount() { console.warn(document.getElementById(‘btn‘)) // null this.setState({ count: this.state.count + 1 }) } render() :
render() { console.warn(document.getElementById(‘btn‘)) // null return ( <div> <button id="btn" onClick={this.handleAdd}>打豆豆一次</button> { this.state.count === 4 ? null : <CounterChild initCount={this.state.count}></CounterChild> } </div> ) } componentDidMount():
componentDidMount() { // 此时,就可以获取到组件内部的DOM对象 console.warn(‘componentDidMount‘,document.getElementById(‘btn‘)) } 接下来是运行交互阶段:
componentWillReceiveProps() :
componentWillReceiveProps(nextProps) { console.warn(‘componentWillReceiveProps‘,nextProps) } shouldComponentUpdate() :
// - 参数: // - 第一个参数:最新属性对象 // - 第二个参数:最新状态对象 shouldComponentUpdate(nextProps,nextState) { console.warn(‘shouldComponentUpdate‘,nextProps,nextState) return nextState.count % 2 === 0 } componentWillUpdate() :
componentWillUpdate(nextProps,nextState) { console.warn(‘componentWillUpdate‘,nextState) } render():
componentDidUpdate()
componentDidUpdate(prevProps,prevState) { console.warn(‘componentDidUpdate‘,prevProps,prevState) } 卸载阶段:
componentWillUnmount()
?六、受控组件和非受控组件 受控组件: 在HTML当中,像 import React from "react" class CommentBox extends React.Component(){ constructor(props){ super(props); this.state={ value:"" } this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event){ this.setState({ value:event.target.value}); } handleSubmit(){ alert(this.state.value); event.preventDefault; } render(){ return( <form onSubmit={this.handleSubmit}> <input type = "text"value ={this.state.value} onClick={this.handleChange}>姓名</input> <input type = "submit">提交</input> </form> ); } } 非受控组件: 非受控组件数据由DOM操作。使用ref从DOM获得表单数据。 class NameForm extends React.Component { constructor(props) { super(props); this.handleSubmit = this.handleSubmit.bind(this); this.input = React.createRef(); } handleSubmit(event) { alert(‘A name was submitted: ‘ + this.input.current.value); event.preventDefault(); } render() { return ( <form onSubmit={this.handleSubmit}> <label> Name: <input type="text" ref={this.input} /> </label> <input type="submit" value="Submit" /> </form> ); } } 七、单身数据流
父子组件数据流传递: class Child extends React.Component{ constructor(props){ super(props); this.state = {} } render(){ return ( <div> {this.props.text} <br /> <button onClick={this.props.refreshParent}> 更新父组件 </button> </div> ) } } class Parent extends React.Component{ constructor(props){ super(props); this.state = {} } refreshChild(){ return (e)=>{ this.setState({ childText: "父组件沟通子组件成功",}) } } refreshParent(){ this.setState({ parentText: "子组件沟通父组件成功",}) } render(){ return ( <div> <h1>父子组件沟通</h1> <button onClick={this.refreshChild()} > 更新子组件 </button> <Child text={this.state.childText || "子组件未更新"} refreshParent={this.refreshParent.bind(this)} /> {this.state.parentText || "父组件未更新"} </div> ) } } 兄弟组件数据传递:借助父组件 class Brother1 extends React.Component{ constructor(props){ super(props); this.state = {} } render(){ return ( <div> <button onClick={this.props.refresh}> 更新兄弟组件 </button> </div> ) } } class Brother2 extends React.Component{ constructor(props){ super(props); this.state = {} } render(){ return ( <div> {this.props.text || "兄弟组件未更新"} </div> ) } } class Parent extends React.Component{ constructor(props){ super(props); this.state = {} } refresh(){ return (e)=>{ this.setState({ text: "兄弟组件沟通成功",}) } } render(){ return ( <div> <h2>兄弟组件沟通</h2> <Brother1 refresh={this.refresh()}/> <Brother2 text={this.state.text}/> </div> ) } } 参考自: https://segmentfault.com/a/1190000006831820 https://segmentfault.com/a/1190000012921279 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |