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. 如果是要同时触发几个button
的onclick
事件,可以在[
里面加上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")
);
能看到一个按下后从
onClick={props.onClick}改为
onClick={props.onClick()}`, 这个按钮在按下之前就直接变成如何取得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的时候有没有加上{
模块 }
符号?