博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
深入理解react
阅读量:6837 次
发布时间:2019-06-26

本文共 3188 字,大约阅读时间需要 10 分钟。

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

createElement和component

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

const Test = (props) => 

hello, {props.name}

;

<Test name="world" />经过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 />,而不是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,会发现拿到的已经是更新后的了。

转载地址:http://vzhkl.baihongyu.com/

你可能感兴趣的文章
谷歌深度学习公开课任务 5: Word2Vec&CBOW
查看>>
让Python不在mac的dock上显示火箭图标
查看>>
Oracle 数据库EM访问多个Instance
查看>>
理解 Delphi 的类(十) - 深入方法[28] - 递归函数实例: 搜索当前目录下的所有嵌套目录...
查看>>
前端纪实
查看>>
学 Win32 汇编[12]: PTR、OFFSET、ADDR、THIS
查看>>
WinAPI: GetLocalTime、SetLocalTime、SetSystemTime - 获取与设置系统时间
查看>>
关于 Delphi 中流的使用(6) 用流读写结构化文件
查看>>
复杂的结构化存取(一)
查看>>
web前端性能优化
查看>>
如何通过jq和php实现返回父级页面(附带记忆功能)
查看>>
Centos下运行gpg --gen-key生成key时出现卡住解决方案笔记
查看>>
Java时间操作工具类
查看>>
XML转JSON的javascript代码
查看>>
PHP冒泡排序详解
查看>>
Zabbi监控系统搭建
查看>>
创建github账号
查看>>
【hibernate系列】采用p6spy+SQLProfiler完整显示hibernate的S...
查看>>
使用varnish + nginx + lua搭建网站的降级系统
查看>>
网页简单配置捉取网购信息
查看>>