2018-03-10


title: react 学习笔记

date: 2018-01-23 00:59:13

tags:


react 心得

React 基础

相关名词

什么是webpack [link][http://geezhawk.github.io/using-react-with-django-rest-framework]

Webpack is a module bundler. It takes JSX, React, and all their dependencies, and compiles them to JavaScript for the browser. It does this by allowing you to plug in whichever loaders you need. More on loaders below. One of the coolest features of webpack is that you can store all your preferences in a single file (webpack.config.js) so that you can build your frontend with just one command.

什么是react.js react-dom.js

react.js文件是创建React元素和组件的核心文件,react-dom.js文件用来把React组件渲染为DOM,此文件依赖于react.js文件,需在其后被引入。

什么是browser.js

首先,你并非必需引入browser.js 引入它的作用是使浏览器支持babel,你可以使用ES2015(javascript下一代标准,具体可以看阮一峰的ECMAScript 6 入门)进行编码。 如果你用ES5,可以不引入

众所周知,React 使用 JSX 来替代常规的 JavaScript,但jsx使用的是ES6b标准,而目前很多浏览器仍然只支持ES5,所以我们就需要将jsx转成普通js。在生产环节中,我们通常直接将jsx编译为js,但自己调试的时候可以加入browser.js在浏览器端转换jsx文件,虽然这样会导致项目加载速度变慢,但却方便与调试。 从Babel 6.0开始,不再直接提供浏览器版本,而是要用构建工具构建出来,这里可以通过安装老版本的babel-core模块来解决

什么是npm

npm is an elegant way to handle frontend dependencies. It saves you from moving a bunch of javascript modules around your staticfiles directories.

webpack-bundle-tracker

This plugin gets useful information from webpack and stores it in a json file. It will help webpack talk with Django.

什么是yarn

Yarn 是一个依赖管理工具。它能够管理你的代码,并与全世界的开发者分享代码。Yarn 是高效、安全和可靠的,你完全可以安心使用。 Yarn 能够让你使用其他开发者开发的代码,让你更容易的开发软件。如果你在使用中发现任何问题,欢迎发 issue 或者贡献代码,一旦问题被修复,你就可以继续使用 Yarn 战斗了。 代码是通过包(有时也被称为模块)进行共享的。 在每一个包中包含了所有需要共享的代码,另外还定义了一个 package.json 文件,用来描述这个包。

babel-loader

According to its documentation, babel-loader allows “transpiling” of Javascript files. That science-fictiony term just means that it takes our JSX code and turns it into plain JavaScript that can run in any browser, anywhere. Remember: a loader is just a JavaScript library that transforms code from one dialect into another.

django-webpack-loader

This uses the webpack-stats.json file to figure out information about the bundles generated by webpack, allowing you to use these bundles in Django.

什么是webpack

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法 a:模块化,让我们可以把复杂的程序细化为小的文件; b:类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能能装换为JavaScript文件使浏览器可以识别; c:scss,less等CSS预处理器 ... 这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。

webpack 跟 gulp/grunt 有什么不同

其实Webpack和另外两个并没有太多的可比性,Gulp/Grunt是一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack可以替代Gulp/Grunt类的工具。 Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,这个工具之后可以自动替你完成这些任务。 Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。

类似gulp把自己定位为stream building tools一样,webpack把自己定位为module building system。 在webpack看来,所以的文件都是模块,只是处理的方式依赖不同的工具而已。 webpack同时也把node的IO和module system发挥的淋漓尽致。 webpack在配合babel(ES6/7)和tsc(typescript)等类似DSL语言预编译工具的时候,驾轻就熟,为开发者带来了几乎完美的体验。

什么是bower

Web sites are made of lots of things — frameworks, libraries, assets, and utilities. Bower manages all these things for you. Keeping track of all these packages and making sure they are up to date (or set to the specific versions you need) is tricky. Bower to the rescue!

Bower是一个包管理工具。包的内容没有限制,比如:js库,框架,图片/字体资源等等或者它们的组合都可以,只要是你需要的就行,你也可以打包一些内容通过在bower上登记注册公开对外发布(当然Bower也支持提建私有包库)。

一、Bowertwitter推出包管理工具。其特点是对包结构没有强制规范,也因此bower本身并不提供一套构建工具,它充当的基本上是一个静态资源的共享平台。bower本身不存储模块文件本身(NPM以及SPM则会将模块作者的文件打包保存在自己的服务器中),也不保存模块的版本信息。模块的发布者通过注册(register)的方式,将模块的可访问的公开的git地址记录在bower的数据库中。而所有的版本都是通过模块发布者自己控制代码库的tag来决定。bower在安装流程基本上可以简单认为是将注册的git地址中的特定tag clone一份到你本地的bower_components 目录中。看起来bower本身提供的功能,以及实现都比价简单,但是它确实使用最广的前端模块管理工具。它在github上的项目有1w+的star。之所以bower能这么流行,得益于它宽松的规范能很好地直接应用在很多已经存在的项目中,所有人都能通过简单地添加一个bower.json以及补充相关信息,不需要修改代码和目录结构,就马上开始使用注册发布自己的模块。

gulp

gulp是什么? gulp是一个基于流的构建工具,可以自动执行指定的任务,简洁且高效 gulp能做什么 开发环境下,想要能够按模块组织代码,监听实时变化 css/js预编译,postcss等方案,浏览器前缀自动补全等 条件输出不同的网页,比如app页面和mobile页面 线上环境下,我想要合并、压缩 html/css/javascritp/图片,减少网络请求,同时降低网络负担

webpack-dev-server 與 react-hot-loader 是什麼

webpack-dev-server 是個小型的 node.js express server,主要用來跑專案內的檔案,同時提供 LiveReload 的功能。react-hot-loader 則是可以在不改變 React 元件的 state 下,將更改過程式碼的元件直接更新到畫面上。

Lodash

JS 太垃圾不方便,但是有个非常好用的 Lodash 库,提供了很多方便的函数,写起来可以很像 Python。如果你也不知道怎么用 Lodash,那么你在 Google 代码例子时,加上 lodash 关键词,比如 “lodash iterate object”。

react + jquery 可以吗

React和jQuery都是做网页的工具,他们的方式不同,但是最终产生的效果都是操作DOM,都用上了React,真的没有必要去用jQuery了,而且两者混用,需要特别小心(并不是说不可能混用),因为React操作的是Virtual DOM然后根据Virtual DOM来修改真正的DOM,加入,React认为Virtual DOM没有修改,但是对应的真正DOM被jQuery修改了,那么React也不会重绘那部分DOM,这可能不是我们想要的结果。

Higher Order Component HOC Tackling HOC in React Native

HOC is a function that takes React Component as input and outputs a new React Component.


//HOC core concept

const HOC = Comp => props =>

//simple sample

function HOC(Comp) {

  return class NewComp extends Component {

    render() {

      return

    }

  }

}

react 错误处理 error handle

component is not mounted

Warning: setState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component.

This is a no-op.

Please check the code for the YOURREACTCOMPONENT component.

这是因为我把部分function call放在constructor上面了,解决方法: 把function call放在componentDidMount

react snippet

React class example


class Square extends React.Component {

  constructor(props) {

    super(props);

    this.state = {

      value: null,

    };

  }

  render() {

    return (

      alert('click')}>

        {this.props.value}

    );

  }

}

react-dom example


ReactDOM.render(

  ,

  document.getElementById('root')

);

react 如何做到click一个button, 同时trigger几个button click event

参考资料 How to manually trigger click event in ReactJS?

1. 在你要被控制Click的Button控件上面增加 ref={e => this.exportButton = e}

2. 然后你就能在其他function里面使用this.exportButton,比如说 this.exportButton.click()

3. 注意喔,如果你的实际响应onclick的是[而不是](https://www.jianshu.com/writer)[, 就应该把ref={input => this.exportButton = input} 放在 ](https://www.jianshu.com/writer)里面

4. 如果是要同时触发几个buttononclick事件,可以在[里面加上target="_blank"](https://www.jianshu.com/writer)


[this.exportButton = input} >Export](http://www.jianshu.com/%7B%60/api/export?${this.state.offsetURL}`})

superClick = () => {

    this.exportButton.click();

  }

react table, pagination 的设置


  rowKey="id"

  columns={this.columns}

  expandedRowRender={record =>

{record.client_group.name}

}

  expandRowByClick={true}

  dataSource={this.state.data}

  pagination={% templatetag openvariable %}

                total: 100,

                current: 1,

                onChange: (page, pageSize) => {

                    console.log('current page: ', page);

                }

              {% templatetag closevariable %}

  size="middle"

/>

react 的render渲染时机

react render渲染的几种情况 1. 首次加载 2. setState改变组件内部state。 注意: 此处是说通过setState方法改变。 3. 接受到新的props

如果用array储存state状态,当状态发生改变时应用.slice()来复制array,然后再赋值给state, 而不是直接改array内的数值

In the previous code example, we suggest using the .slice() operator to copy the squares array prior to making changes and to prevent mutating the existing array.


handleClick(i){

    console.log("test" + i);

    const squares = this.state.squares.slice();

    squares[i] = "O";

    this.setState({

      squares: squares

    });

}

一个components 只包含render(),与其继承React.Component,可以使用Functional Components(记得把'this'去掉,以及onClick={() => props.onClick()} 改成 onClick={props.onClick})


class Square extends React.Component {

  render() {

    return (

      this.props.onClick()}>

        {this.props.value}

    );

  }

}

//改成

function Square(props) {

  return (

      {props.value}

  );

}

error boundary, 一个react的error catching 机制


class ErrorBoundary extends React.Component {

  constructor(props) {

    super(props);

    this.state = { hasError: false };

  }

  componentDidCatch(error, info) {

    // Display fallback UI

    this.setState({ hasError: true });

    // You can also log the error to an error reporting service

    logErrorToMyService(error, info);

  }

  render() {

    if (this.state.hasError) {

      // You can render any custom fallback UI

      return

# Something went wrong.

;

    }

    return this.props.children;

  }

}

//用法

在react的官方教程link, 着这一段话

While we’re cleaning up the code, we also changed onClick={() => props.onClick()} to just onClick={props.onClick}, as passing the function down is enough for our example. Note that onClick={props.onClick()} would not work because it would call props.onClick immediately instead of passing it down

该怎么理解?什么时候用onClick={props.onClick},什么时候用 onClick={props.onClick()}?

onClick={props.onClick} 实际等于 onClick={() => props.onClick()}, 不等于onClick={props.onClick()},后者的会马上执行,原理跟setTimeout(function(){DoSomeThing()},1000)setTimeout(DoSomeThing(),1000)一样

例子

class Square extends React.Component {

render() {

return (

    {this.props.value}

);

}

}

class Board extends React.Component {

constructor(props) {

super(props);

this.state = ({value : "O"});

}

render() {

return (

  {this.setState({value:"X"})}}/>

)

}

}

ReactDOM.render(

,

document.getElementById("root")

);

能看到一个按下后从

O
O
变成
X
X
的按钮,如果把上文的onClick={props.onClick}改为onClick={props.onClick()}`, 这个按钮在按下之前就直接变成
X
X

如何取得setState之前的数据 (prevState)

class Player extends React.Component {

constructor() {

super()

this.state = { score: 0 }

}

increaseScore() {

// 1\. Get previous state from this.state

this.setState({ score: this.state.score + 1 })

// 2\. Get previous state from the callback function

this.setState((prevState) => {

  return { score: prevState.score + 1 }

})

}

}

错误解析

main-a4bb720558d852fd7634.js:10491 Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.

这个错误多是因为某个tag对应的class不存在,检查一下是不是有class忘记export了?或者export default?

import的时候有没有加上{ 模块 } 符号?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343