wuyuanlijie / blog

🔥JerryLeeFE工作总结
1 stars 0 forks source link

React在工作中的使用总结 #1

Open wuyuanlijie opened 6 years ago

wuyuanlijie commented 6 years ago

1.React组件的生命周期:

React 生命周期分为三种状态 1. 初始化 2.更新 3.销毁

图片

1. 初始化阶段

3. React RouterV4 在react中的使用

React RouterV4遵循了React的理念:万物皆组件。 React RouterV4基于Learn管理多个Repository,其代码库包括:

  1. react-router React Router的核心
  2. react-router-dom 用于DOM绑定的React Router
  3. react-router-native 用于React Native的React Router
  4. react-router-redux React Router和Redux的集成
  5. react-router-config 静态路由的配置帮组助手

4. this.setState更新的问题

  • this.setState是异步的,所以在this.setState之后立即调用this.state是获取不到最新的数据的。

下面介绍三种方法来获取最新的数据: 1.回调函数

this.setState({
  val: this.state.val + 1
}, () => {console.log(this.state.val)});

2.利用componentDidUpdate,因为在这个生命周期函数,说明页面已经渲染完成state、props都已经被渲染好了

componentDidUpdate(){
  console.log(this.state.val);
}

3.将this.setState放入到setTimeout函数中(因为在this.setState之后this.state是立即更新的!)

let self = this;
setTimeout(function(){
  self.setState({
    val: this.state.val + 1
  });
  console.log(self.state.val);
})

5. this.props.children容器类组件

6. Props和State

  • React的核心思想就是组件化的思想,组件根据props和state两个参数,计算得到对应的界面的UI。可见,props和state是组件两个重要的数据来源。
  • props是组件对外的接口,state是组件对内的接口。组件内部可以引用其他的组件,组件之间的引用就形成了一个树状的结构(组件树)。组件的props数据,上层组件就可以通过下层组件的props属性进行传递。组件自身的也需要维护组件的数据,这就是对内的state。

如何设置一个组件state?

state必须能代表一个组件的UI呈现的完整状态集,组件对应UI的任何变化,都可以从state变化中反映出来,同时,state还必须是代表一个组件UI呈现的最小状态集。

  1. 变量是通过props从父组件获取的,则不是一个状态。
  2. 变量在组件的整个生命周期都保持不变的,则不是一个状态。
  3. 变量是可以通过state或props的已有数据获取得到的,则不是一个状态。
  4. 变量不在组件render中使用,则不是一个状态。这个变量更适合定义为组件的一个普通的属性。

如何正确的修改state

  1. 不能直接修改state

    直接修改state,组件不会重新触发render

  2. state的更新是异步的

    setState只是把修改的状态放入一个队列中,React会优化真正的时机,并且React会出于性能的问题,可能会多次将setState的状态修改合并成一次状态的修改。props的更新也是异步的。例如当我们连续点击两次按钮,连续调用两次this.setState,在React合并多次修改为一次的情况下,相当执行了以下的代码。后面的操作会覆盖前面的操作,最终的购买数量就只增加1个。

    // 错误 这里只会触发一个添加的事件
    Object.assign(
    previousState,
    {quantity: this.state.quantity + 1},
    {quantity: this.state.quantity + 1}
    )
    // 正确 接收一个函数作为参数的setState、第一个参数是组件修改组件前的state,后面是组件最新的props
    this.setState((preState, props) => {
    counter: preState.quantity + 1,
    })

    3.state更新是一个浅合并(Shallow Merge)的过程 当调用setState修改组件的时候,只需要传入发生改变的状态变量,而不是组件完整的state,因为组件的的更新是一个浅合并的过程。只需要修改我们需要去修改的即可。

React建议我们把state当作一个不可变的对象,

  1. 状态的类型是不可变类型(数字、字符串、布尔值、null、undefined)
  2. 状态的类型是数组 如有一个数组类型的状态books,当向books中增加一本书时,使用数组的concat方法或ES6的数组扩展语法(spread syntax)
    // 方法一 concat
    this.setState(preState => ({  // 返回一个对象 return {...}
    books: preState.books.concat(['React Book'])   // concat用于连接一个或多个数组。
    }))
    // 方法二 ES6 展开运算符
    this.setState(preState => {
    books: [...preState.books, 'React Book']
    }))

    还可以使用slice来截取数组,使用filter来过滤数组,在setState里面参数添加一个函数,函数的参数是修改前的state。(concat、filter、slice返回一个新的数组,主要不要使用push、pop、shift、unshift、splice等方法修改数组,因为它们是在原数组的基础上修改的。)

  3. 状态的类型是简单的对象 修改state中对象的方法的时候,以下的两种方式:
    this.state = {
    owner = {
    name: '李杰',
    age: 20
    }
    }
    // 使用ES6的Object.assign方法
    this.setState(preState => ({
    // Object.assign用于将所有可枚举属性的值从一个或多个源对象复制到目标对象
    owner: Object.assign({}, preState.owner, {name: 'lijie'})
    })
    )
    // 对象的展开运算符
    this.setState(preState => ({
    owner: {...preState.owner, name: 'lijie'}
    })
    )

    => React建议state不可变对象,所以当组件某个状态发生改变的时候,我们应该重新去创建一个新的状态,而不是修改原来的状态。避免重新去直接修改原对象的方法。

    为什么React推荐组件的状态不可变对象?

    • 一是方便管理和调试
    • 二是出于性能的考虑,组件的状态是不可变的对象的时候,我们在组件的shouldComponentUpdate的方法中,仅需要比较状态的引用就可以判断状态是否改变,从而避免了不必要的render方法的调用。
wuyuanlijie commented 6 years ago

学会去在react中使用箭头函数,箭头函数中的this指向为:当前调用对象的所在的上下文环境,也就是当前的组件。() => {}

wuyuanlijie commented 6 years ago

问题:React.createClass会自动绑定每个方法的this到当前组件中,但是使用ES6 class或者纯函数的时候,我们需要手动去绑定this!

React中绑定this的几种方法:

  1. bind:直接在方法的内部添加bind
    render () {
    return (
        <button onClick={ this.handleClick.bind(this, '李杰') }>点我、点我</div>
    )
    }
  2. 构造函数内绑定
    
    constructor(props) {
    super(props);
    this.handleClick = this.handle.bind(this);
    }

// 这里我们也可以使用ES7的语法糖 constructor(props) { super(props); this.handleClick = ::this.handleClick; }

3. 箭头函数:会捕捉其所在的上下文this的值,作为自己的this的值。

render () { return ( <button onClick={ () => this.handleClick() }>点我、点我

) }

// 当然我们还可以这么写 handleClick = (e) => { console.log(this.state.message) } render () { return ( <button onClick={ this.handleClick }>点我、点我

) }