2018-03-10


title: react 學(xué)習(xí)筆記

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

tags:


react 心得

React 基礎(chǔ)

相關(guān)名詞

什么是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文件是創(chuàng)建React元素和組件的核心文件,react-dom.js文件用來把React組件渲染為DOM,此文件依賴于react.js文件,需在其后被引入。

什么是browser.js

首先,你并非必需引入browser.js 引入它的作用是使瀏覽器支持babel,你可以使用ES2015(javascript下一代標(biāo)準(zhǔn),具體可以看阮一峰的ECMAScript 6 入門)進(jìn)行編碼。 如果你用ES5,可以不引入

眾所周知,React 使用 JSX 來替代常規(guī)的 JavaScript,但jsx使用的是ES6b標(biāo)準(zhǔn),而目前很多瀏覽器仍然只支持ES5,所以我們就需要將jsx轉(zhuǎn)成普通js。在生產(chǎn)環(huán)節(jié)中,我們通常直接將jsx編譯為js,但自己調(diào)試的時(shí)候可以加入browser.js在瀏覽器端轉(zhuǎn)換jsx文件,雖然這樣會(huì)導(dǎo)致項(xiàng)目加載速度變慢,但卻方便與調(diào)試。 從Babel 6.0開始,不再直接提供瀏覽器版本,而是要用構(gòu)建工具構(gòu)建出來,這里可以通過安裝老版本的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 是一個(gè)依賴管理工具。它能夠管理你的代碼,并與全世界的開發(fā)者分享代碼。Yarn 是高效、安全和可靠的,你完全可以安心使用。 Yarn 能夠讓你使用其他開發(fā)者開發(fā)的代碼,讓你更容易的開發(fā)軟件。如果你在使用中發(fā)現(xiàn)任何問題,歡迎發(fā) issue 或者貢獻(xiàn)代碼,一旦問題被修復(fù),你就可以繼續(xù)使用 Yarn 戰(zhàn)斗了。 代碼是通過包(有時(shí)也被稱為模塊)進(jìn)行共享的。 在每一個(gè)包中包含了所有需要共享的代碼,另外還定義了一個(gè) package.json 文件,用來描述這個(gè)包。

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

本質(zhì)上,webpack 是一個(gè)現(xiàn)代 JavaScript 應(yīng)用程序的靜態(tài)模塊打包器(module bundler)。當(dāng) webpack 處理應(yīng)用程序時(shí),它會(huì)遞歸地構(gòu)建一個(gè)依賴關(guān)系圖(dependency graph),其中包含應(yīng)用程序需要的每個(gè)模塊,然后將所有這些模塊打包成一個(gè)或多個(gè) bundle。

WebPack可以看做是模塊打包機(jī):它做的事情是,分析你的項(xiàng)目結(jié)構(gòu),找到JavaScript模塊以及其它的一些瀏覽器不能直接運(yùn)行的拓展語言(Scss,TypeScript等),并將其打包為合適的格式以供瀏覽器使用。

今的很多網(wǎng)頁其實(shí)可以看做是功能豐富的應(yīng)用,它們擁有著復(fù)雜的JavaScript代碼和一大堆依賴包。為了簡化開發(fā)的復(fù)雜度,前端社區(qū)涌現(xiàn)出了很多好的實(shí)踐方法 a:模塊化,讓我們可以把復(fù)雜的程序細(xì)化為小的文件; b:類似于TypeScript這種在JavaScript基礎(chǔ)上拓展的開發(fā)語言:使我們能夠?qū)崿F(xiàn)目前版本的JavaScript不能直接使用的特性,并且之后還能能裝換為JavaScript文件使瀏覽器可以識(shí)別; c:scss,less等CSS預(yù)處理器 ... 這些改進(jìn)確實(shí)大大的提高了我們的開發(fā)效率,但是利用它們開發(fā)的文件往往需要進(jìn)行額外的處理才能讓瀏覽器識(shí)別,而手動(dòng)處理又是非常繁瑣的,這就為WebPack類的工具的出現(xiàn)提供了需求。

webpack 跟 gulp/grunt 有什么不同

其實(shí)Webpack和另外兩個(gè)并沒有太多的可比性,Gulp/Grunt是一種能夠優(yōu)化前端的開發(fā)流程的工具,而WebPack是一種模塊化的解決方案,不過Webpack的優(yōu)點(diǎn)使得Webpack可以替代Gulp/Grunt類的工具。 Grunt和Gulp的工作方式是:在一個(gè)配置文件中,指明對(duì)某些文件進(jìn)行類似編譯,組合,壓縮等任務(wù)的具體步驟,這個(gè)工具之后可以自動(dòng)替你完成這些任務(wù)。 Webpack的工作方式是:把你的項(xiàng)目當(dāng)做一個(gè)整體,通過一個(gè)給定的主文件(如:index.js),Webpack將從這個(gè)文件開始找到你的項(xiàng)目的所有依賴文件,使用loaders處理它們,最后打包為一個(gè)瀏覽器可識(shí)別的JavaScript文件。

類似gulp把自己定位為stream building tools一樣,webpack把自己定位為module building system。 在webpack看來,所以的文件都是模塊,只是處理的方式依賴不同的工具而已。 webpack同時(shí)也把node的IO和module system發(fā)揮的淋漓盡致。 webpack在配合babel(ES6/7)和tsc(typescript)等類似DSL語言預(yù)編譯工具的時(shí)候,駕輕就熟,為開發(fā)者帶來了幾乎完美的體驗(yàn)。

什么是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是一個(gè)包管理工具。包的內(nèi)容沒有限制,比如:js庫,框架,圖片/字體資源等等或者它們的組合都可以,只要是你需要的就行,你也可以打包一些內(nèi)容通過在bower上登記注冊(cè)公開對(duì)外發(fā)布(當(dāng)然Bower也支持提建私有包庫)。

一、Bowertwitter推出包管理工具。其特點(diǎn)是對(duì)包結(jié)構(gòu)沒有強(qiáng)制規(guī)范,也因此bower本身并不提供一套構(gòu)建工具,它充當(dāng)?shù)幕旧鲜且粋€(gè)靜態(tài)資源的共享平臺(tái)。bower本身不存儲(chǔ)模塊文件本身(NPM以及SPM則會(huì)將模塊作者的文件打包保存在自己的服務(wù)器中),也不保存模塊的版本信息。模塊的發(fā)布者通過注冊(cè)(register)的方式,將模塊的可訪問的公開的git地址記錄在bower的數(shù)據(jù)庫中。而所有的版本都是通過模塊發(fā)布者自己控制代碼庫的tag來決定。bower在安裝流程基本上可以簡單認(rèn)為是將注冊(cè)的git地址中的特定tag clone一份到你本地的bower_components 目錄中??雌饋韇ower本身提供的功能,以及實(shí)現(xiàn)都比價(jià)簡單,但是它確實(shí)使用最廣的前端模塊管理工具。它在github上的項(xiàng)目有1w+的star。之所以bower能這么流行,得益于它寬松的規(guī)范能很好地直接應(yīng)用在很多已經(jīng)存在的項(xiàng)目中,所有人都能通過簡單地添加一個(gè)bower.json以及補(bǔ)充相關(guān)信息,不需要修改代碼和目錄結(jié)構(gòu),就馬上開始使用注冊(cè)發(fā)布自己的模塊。

gulp

gulp是什么? gulp是一個(gè)基于流的構(gòu)建工具,可以自動(dòng)執(zhí)行指定的任務(wù),簡潔且高效 gulp能做什么 開發(fā)環(huán)境下,想要能夠按模塊組織代碼,監(jiān)聽實(shí)時(shí)變化 css/js預(yù)編譯,postcss等方案,瀏覽器前綴自動(dòng)補(bǔ)全等 條件輸出不同的網(wǎng)頁,比如app頁面和mobile頁面 線上環(huán)境下,我想要合并、壓縮 html/css/javascritp/圖片,減少網(wǎng)絡(luò)請(qǐng)求,同時(shí)降低網(wǎng)絡(luò)負(fù)擔(dān)

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

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

Lodash

JS 太垃圾不方便,但是有個(gè)非常好用的 Lodash 庫,提供了很多方便的函數(shù),寫起來可以很像 Python。如果你也不知道怎么用 Lodash,那么你在 Google 代碼例子時(shí),加上 lodash 關(guān)鍵詞,比如 “l(fā)odash iterate object”。

react + jquery 可以嗎

React和jQuery都是做網(wǎng)頁的工具,他們的方式不同,但是最終產(chǎn)生的效果都是操作DOM,都用上了React,真的沒有必要去用jQuery了,而且兩者混用,需要特別小心(并不是說不可能混用),因?yàn)镽eact操作的是Virtual DOM然后根據(jù)Virtual DOM來修改真正的DOM,加入,React認(rèn)為Virtual DOM沒有修改,但是對(duì)應(yīng)的真正DOM被jQuery修改了,那么React也不會(huì)重繪那部分DOM,這可能不是我們想要的結(jié)果。

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 錯(cuò)誤處理 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.

這是因?yàn)槲野巡糠謋unction 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一個(gè)button, 同時(shí)trigger幾個(gè)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. 注意喔,如果你的實(shí)際響應(yīng)onclick的是[而不是](http://www.itdecent.cn/writer)[, 就應(yīng)該把ref={input => this.exportButton = input} 放在 ](http://www.itdecent.cn/writer)里面

4. 如果是要同時(shí)觸發(fā)幾個(gè)buttononclick事件,可以在[里面加上target="_blank"](http://www.itdecent.cn/writer)


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

superClick = () => {

    this.exportButton.click();

  }

react table, pagination 的設(shè)置


  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渲染時(shí)機(jī)

react render渲染的幾種情況 1. 首次加載 2. setState改變組件內(nèi)部state。 注意: 此處是說通過setState方法改變。 3. 接受到新的props

如果用array儲(chǔ)存state狀態(tài),當(dāng)狀態(tài)發(fā)生改變時(shí)應(yīng)用.slice()來復(fù)制array,然后再賦值給state, 而不是直接改array內(nèi)的數(shù)值

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

    });

}

一個(gè)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, 一個(gè)react的error catching 機(jī)制


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

該怎么理解?什么時(shí)候用onClick={props.onClick},什么時(shí)候用 onClick={props.onClick()}?

onClick={props.onClick} 實(shí)際等于 onClick={() => props.onClick()}, 不等于onClick={props.onClick()},后者的會(huì)馬上執(zhí)行,原理跟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")

);

能看到一個(gè)按下后從

O
O
變成
X
X
的按鈕,如果把上文的onClick={props.onClick}改為onClick={props.onClick()}`, 這個(gè)按鈕在按下之前就直接變成
X
X

如何取得setState之前的數(shù)據(jù) (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 }

})

}

}

錯(cuò)誤解析

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.

這個(gè)錯(cuò)誤多是因?yàn)槟硞€(gè)tag對(duì)應(yīng)的class不存在,檢查一下是不是有class忘記export了?或者export default?

import的時(shí)候有沒有加上{ 模塊 } 符號(hào)?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容