react v16.2.0

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ming_221/article/details/82805520

#react v16.2.0

react 16

componentWillMount可能会被执行多次。

Calling setState with null no longer triggers an update

setState callbacks (second argument) now fire immediately after componentDidMount / componentDidUpdate instead of after all components have rendered.
JSX

默认情况下, 在渲染之前, React DOM 会格式化(escapes) JSX中的所有值. 从而保证用户无法注入任何应用之外的代码. 在被渲染之前,所有的数据都被转义成为了字符串处理。 以避免 XSS(跨站脚本) 攻击

元素elements 是React应用中最小的构建部件(构建块,building blocks)。

关注每个时间点UI的表现, 而不是关注随着时间不断更新UI的状态, 可以减少很多奇怪的 bug 。

所有React组件都必须是纯函数(不改变自身的输入值),并禁止修改自身props

函数式组件(Functional)

//接收props参数,返回一个React元素
function Welcome(props){
	return <h1>Hello,{ props.name }</h1>
}

类组件

//有额外的特性
//类允许在其中添加本地状态(state)和生命周期钩子
class Welcome extends React.Component{
	render() {
		return <h1>Hello, { this.props.name }</h1>;
	}
}

diff

  1. 根元素类型不同全部重绘,state(状态)都会丢失

     // 销毁旧的Counter,重新装载(remount)一个新的
     <div>
       <Counter />
     </div>
     
     <span>
       <Counter />
     </span>
    
  2. 比较两个相同类型的React DOM,保留相同的底层DOM节点,只更新发生改变的属性(attributes)

    // 只修改color,不修改fontWeight
    <div style={{color: 'red', fontWeight: 'bold'}} />
    
    <div style={{color: 'green', fontWeight: 'bold'}} />
    
    componentWillReceiveProps() => componentWillUpdate() => render()
    
  3. 递归处理子元素

key值作为同类型子节点的唯一识别码,避免插入引起的子节点全部重绘,提高渲染效率。

key值应该是稳定的,可预测的,唯一的。不稳定的 key (类似于 Math.random() 函数的结果)可能会产生非常多的组件实例并且 DOM 节点也会非必要性的重新创建。这将会造成极大的性能损失和组件内state的丢失。

受控组件

每一次state变化都会伴有相关联的处理函数,可以直接修改或验证用户的输入(onChange)

// onChange函数获取的value实际上是修改后的值,可能和当前页面显示的值不一样
class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
  	//此处弹出的是修改后的值,并不是input里显示的value值
    alert(event.target.value)
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('A name was submitted: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.props.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm value="1222" />,
  document.getElementById('root')
);

组件包含

组件可以接受任意的 props(属性) ,包括原始值、React 元素,或者函数。如 和 等 React 元素本质上也是对象,所以可以将其像其他数据一样作为 props(属性) 传递使用。

如果要在组件之间重用非 U I功能,我们建议将其提取到单独的 JavaScript 模块中。组件可以导入它并使用该函数,对象或类,而不扩展它。

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane left={<Contacts />} right={<Chat />} />
  );
}

生命周期函数

首次渲染
  1. 构造函数(仅调用一次)

     // es6
     constructor(props){
     	super(props);
     }
     // es5
     getDefaultProps()
     getInitialState(){ return {} }
    
  2. componentWillMount()(仅调用一次)

    ??? 由componentWillMount 引发的血案(莫名其妙的报错,或者Action调用不执行,无法获取数据): UNSAFE_componentWillMount

     * This is the only lifecycle hook called on server rendering.
     	
     * This lifecycle was previously named componentWillMount. That name will continue to work until version 17. Use the rename-unsafe-lifecycles codemod to automatically update your components.
    
    • react16.0以后,componentWillMount可能会被执行多次。

    • componentWillMount中ajax参数错误会导致白屏,阻断页面渲染,连接报错则页面正常渲染;在 ajax success 中执行的操作会导致页面渲染暂停

    • 渲染过程中出错似乎会尝试重新渲染组件一次,即 重新从willMount开始调用

    • willMount 里的setState会触发render(will not trigger an extra rendering),且setState的数据可在render中获取,缩短了渲染过程。但如果 componentWillMount 里setState 的数据是异步获取的,则渲染步骤和 componentDidMount 中获取数据并无不同。

    didMount中的setState

     	componentDidMount (){
            console.log('announce: willMount')
         	this.setState({id: 2}, function(){
     	        console.log('announce: setState')
     	    });
     	}
     	
     	announce: willMount
     	announce: render undefined
     	announce: announceListRender
     	Pagination: willMount
     	Pagination: didMount
     	announce: didMount
     	announce: render 2
     	announce: announceListRender
     	Pagination: shouldComponentUpdate
     	announce: didUpdate
     	announce: setState
    

    willMount中的setState

     	componentWillMount (){
            console.log('announce: willMount')
         	this.setState({id: 2}, function(){
     	        console.log('announce: setState')
     	    });
     	}
     	
     	announce: willMount
     	announce: render 2
     	announce: announceListRender
     	Pagination: willMount
     	Pagination: didMount
     	announce: didMount
     	announce: setState
    
  3. render()

  4. componentDidMount()(仅调用一次)

更新 (初次渲染不触发)
  1. componentWillReceiveProps(nextProps)
  2. shouldComponentUpdate(nextProps, nextStates)
  3. componentWillUpdate()
  4. render()
  5. componentDidUpdate()

setState: 猜测:setState的操作会立即改变数据 即 setState是同步的,但是,改变的数据可能会延迟等到下一次render的时候显示出来

// setState 的 callback 的输出位置在didUpdate之后
t.setState((prevState, props) => {
    console.log('announce: setState')
}, () => {
    console.log('announce: didSetState')
});

componentDidUpdate(){
    console.log('announce: didUpdate')
  }
强制更新

forceUpdate(skipping shouldComponentUpdate()。This will trigger the normal lifecycle methods for child components, including the shouldComponentUpdate() method of each child forceUpdate更新不受shouldComponentUpdate控制,但是forceUpdate引起render之后所有生命周期函数正常触发,包括子组件的shouldComponentUpdate)

销毁

componentWillUnmount()

reflux

Action

  1. many stores can listen for a single action

Store

  1. 每个Store是一个单例
  2. 可引入多个Store
  3. this.storeKeys 可以控制引入到组件内的 state,确保引入的 stores 不会覆盖组件内的 state

优势:可统一管理状态,可自由组合并选取需要的状态

react & redux chrome extension

自己下载源码 build extension
redux
react

--------------- 2018.6.7

猜你喜欢

转载自blog.csdn.net/ming_221/article/details/82805520
今日推荐