资讯专栏INFORMATION COLUMN

深入理解react

CoderStudy / 1537人阅读

摘要:最近在看源码,发觉以前对的理解实在浮浅,这里记录了一些以前疏忽的点。和在里面,经过的解析后,会变成执行后的结果。原来对的理解就是类似这种写法,现在看了实现之后才理解。

最近在看react源码,发觉以前对react的理解实在浮浅,这里记录了一些以前疏忽的点。

createElement和component

在react里面,经过babel的解析后,jsx会变成createElement执行后的结果。

const Test = (props) => 

hello, {props.name}

;

经过babel解析后会变为createElement(Test, {name: "world}),这里的Test就是上面的Test方法,name就是Test方法里面接受的props中的name。
实际上当我们从开始加载到渲染的时候做了下面几步:

// 1. babel解析jsx
 -> createElement(Test, {name: "world"})
// 2. 对函数组件和class组件进行处理
// 如果是类组件,不做处理,如果是函数组件,增加render方法
const props = {name: world};
const newTest = new Component(props);
newTest.render = function() {
    return Test(props);
}
// 3. 执行render方法
newTest.render();
key

react中的diff会根据子组件的key来对比前后两次virtual dom(即使前后两次子组件顺序打乱),所以这里的key最好使用不会变化的值,比如id之类的,最好别用index,如果有两个子组件互换了位置,那么index就会导致diff全部失效。

cloneElement

原来对cloneElement的理解就是类似cloneElement(App, {})这种写法,现在看了实现之后才理解。原来第一个参数应该是一个reactElement,而不是一个reactComponent,应该是,而不是App,这个也确实是我没有好好看文档。

setState

react里面setState后不会立即更新,但在某些场景下也会立即更新,下面这几种情况打印的值你都能回答的上来吗?

class App extends React.Component {
    state = {
        count: 0;
    }
    test() {
        this.setState({
            count: this.state.count + 1
        }); 
        console.log(this.state.count); // 此时为0
        this.setState({
            count: this.state.count + 1
        });
        console.log(this.state.count); // 此时为0
    }
    test2() {
        setTimeout(() => {
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count); // 此时为1
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count); // 此时为2
        })
    }
    test3() {
        Promise.resolve().then(() => {
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count); // 此时为1
            this.setState({
                count: this.state.count + 1
            });
            console.log(this.state.count); // 此时为2
        })
    }
    test4() {
        this.setState(prevState => {
            console.log(prevState.count); // 0
        return {
            count: prevState.count + 1
        };
        });
        this.setState(prevState => {
            console.log(prevState.count); // 1
            return {
                count: prevState.count + 1
            };
        });
    }
    async test4() {
        await 0;
        this.setState({
            count: this.state.count + 1
        });
        console.log(this.state.count); // 此时为1
        this.setState({
            count: this.state.count + 1
        });
        console.log(this.state.count); // 此时为2
    }
}

在react中为了防止多次setState导致多次渲染带来不必要的性能开销,所以会将待更新的state放到队列中,等到合适的时机(一般是组件第一次渲染或触发事件后)后进行batchUpdate,所以在setState后无法立即拿到更新后的state,很多人说setState是异步的,setState表现确实是异步,只是里面没有用异步代码实现。
如果是给setState传入一个函数,这个函数是执行前一个setState后才被调用的,所以函数返回的参数可以拿到更新后的state。
但是如果将setState在异步方法中(setTimeout、Promise等等)调用,由于方法是异步的,会导致组件pending结束后才执行异步方法中的setState,这个时候由于组件已经不处于pending状态了,会导致setState立即执行,这时通过this.state可以拿到最新的值。

ref

ref用到原生的标签上,可以直接在组件内部用this.refs.xxx的方法获取到真实DOM。
ref用到组件上,需要用ReactDOM.findDOMNode(this.refs.xxx)的方式来获取到这个组件对应的DOM节点。

shouldComponentUpdate

当shouldComponentUpdate返回false的时候,组件没有重新渲染,但是更新后的state和props已经挂载到了组件上面,这个时候如果打印state和props,会发现拿到的已经是更新后的了。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/99704.html

相关文章

  • 深入理解Webpack核心模块Tapable钩子[同步版]

    摘要:本文将根据以下章节分别梳理每个钩子同步钩子首先安装是简单的同步钩子,它很类似于发布订阅。至此,我们把的所有同步钩子都解析完毕异步钩子比同步钩子麻烦些,我们会在下一章节开始解析异步的钩子传送门深入理解核心模块钩子异步版代码 记录下自己在前端路上爬坑的经历 加深印象,正文开始~ tapable是webpack的核心依赖库 想要读懂webpack源码 就必须首先熟悉tapableok.下面是...

    cangck_X 评论0 收藏0
  • React 深入系列1:React 中的元素、组件、实例和节点

    摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 文:徐超,《React进阶之路》作者授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解...

    techstay 评论0 收藏0
  • React.js 小书 Lesson20 - 更新阶段的组件生命周期

    摘要:所以对于组件更新阶段的组件生命周期,我们简单提及并且提供一些资料给大家。这里为了知识的完整,补充关于更新阶段的组件生命周期你可以通过这个方法控制组件是否重新渲染。大家对这更新阶段的生命周期比较感兴趣的话可以查看官网文档。 React.js 小书 Lesson20 - 更新阶段的组件生命周期 本文作者:胡子大哈本文原文:http://huziketang.com/books/react...

    Yumenokanata 评论0 收藏0
  • React 深入系列7:React 常用模式

    摘要:本篇是深入系列的最后一篇,将介绍开发应用时,经常用到的模式,这些模式并非都有官方名称,所以有些模式的命名并不一定准确,请读者主要关注模式的内容。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 本篇是React深入系列的最后一篇,将介绍开发React应用时,经常用到的模式,这些模式并非都有...

    Chao 评论0 收藏0
  • React 深入系列1:React 中的元素、组件、实例和节点

    摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 React 中的元素、组件、实...

    LeviDing 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<