一天學習React入門後的千字基礎總結

一天入門React學習心得

閱讀前必讀

本文寫的倉促,算是一個學習筆記吧,算是一個入門級的學習文章。若是你剛剛入門,那麼可能一些入門的視頻可能更加適合你。但若是具有一些知識,好比Vue,那麼視頻就不適合了。建議看完本篇文章在腦海中過一遍映像,在去官網深讀,和一些深刻文章,想來會有很是好的提高。css

一個框架不是看幾篇文章,寫寫Demo就能說本身會,熟悉。須要不斷實踐,踩坑,學習原理。多想才能掌握。我只是結合Vue進行的React學習,只是冰山一角罷了。充其量只是API的搬運工。react

- - QAQ

初始化項目

新手仍是推薦官方的腳手架,經過npx來進行項目的初始化一個demo項目。git

npx create-react-app 項目名稱
複製代碼

默認生成的目錄狀況下,項目的解構就是這樣的。github

Mode                LastWriteTime         Length Name
---- ------------- ------ ---- d----- 20.6.15 14:21 public d----- 20.6.15 16:41 src -a---- 20.6.15 14:21 310 .gitignore -a---- 20.6.15 14:22 746 package.json -a---- 20.6.15 14:21 2884 README.md -a---- 20.6.15 14:22 526017 yarn.lock 複製代碼

隨後經過npm 或者 yarn 來將項目跑起來。執行shell後會自動打開一個瀏覽器,當看到localhost:3000渲染後。那麼就能夠開啓React大門了web

# npm shell 命令
npm run start  # yarn shell 命令 yarn start 複製代碼

React元素渲染-JSX

Vuetemplate模板獲得大量的使用,只要你會寫HTML那麼應該難不倒你這個小機靈鬼。而React則是使用了在函數中直接返回DOM。看起來很是的神奇,也致使了一些小夥伴在入門的時候會有點摸不着頭腦,可是若是有必定基礎,在Vue中寫過了Render 函數的話,我想上手起來仍是很是容易的。它看起來是下面這個樣子的。其本質上就是一個createElement的過程。因此,將這種模板的渲染方式稱之爲JSXshell

import React from 'react';
import './App.css';  function App() {  return (  <div className="App">  <h1>你好呀</h1>  <p>今天又是充滿但願的一天...</p>  </div>  ); } export default App; 複製代碼

經過React的JSX模板引擎,最終將其渲染到DOM上npm

變量綁定

Vue的模板中,經過{{}}兩個花括號來聲明約束,表示這個聲明中的字段是一個js的值,而不是一個文本。在React則是使用了{}一個花括號來作約定。那麼就能夠在DOM中使用js了。下面是一個Class組件,將statetext值綁定在DOM的。json

class App extends React.Component {
 constructor (props) {  super(props)  this.state = {  text: '我是wangly19'  }  }   updateText () {  this.setState({  text: '我是帥氣的wangly19'  })  }   render () {  return (  <div className="App">  <p>我是一個動態的數據: {this.state.text}</p>  <button onClick={ this.updateText.bind(this) }>更換</button>  </div>  )  } } 複製代碼
結果
結果

條件渲染

Vue中,若是須要動態的渲染一個節點,是經過v-if指令來實現的,在React中呢,可使用運算符來渲染元素。經過Vue來作一個對比吧。redux

經過&&(或)運算符來達到v-if的同樣效果。數組

- - QAQ
render () {
 return (  <div className="App">  <p>我是一個動態的數據: {this.state.text}</p>  {/* { <p v-if="true">2</p> } */}  {true && <p>2</p>}  </div>  ) } 複製代碼

經過三元運算符能夠來達到v-ifv-else同樣的效果。

- - QAQ
render () {
 return (  <div className="App">  <p>我是一個動態的數據: {this.state.text}</p>  {/* { <p v-if="true">2</p> } */}  {true ? <p>true</p> : <p>false</p>}  </div>  ) } 複製代碼

列表渲染

經過map方法來遍歷一些基本數據結構的節點。

經過數據結構自帶的map能夠遍歷出value,index,keyreturn中返回節點信息。

- - QAQ

事件處理

JavaScript中,經過onClick來綁定一個事件。

<button onclick="activeBuff">激活按鈕</button>
複製代碼

而在jsx中,則是經過onClick屬性,且後面加一個jsx渲染模板的方式。

須要注意的是,Class組件下的this是不存在的,須要用戶手動爲方法綁定this,在調用的點擊事件方法。

- - QAQ
<button onClick={ this.activeBuff.bind(this) }>激活按鈕</button> 複製代碼

組件

衆所周知,VueReact都是組件化解決方案,那麼在React中是如何建立一個組件的呢?在React新版本中,推出了React Hooks方案。因此如今主流的仍是Class組件和Function組件。

Class組件

Class組件的建立方式很是的簡單,只須要建立一個Class類而且讓它繼承React.Component,在Render方法中return出JSX的模板。

同時經過構造函數,處理Props。而且聲明state狀態初始化一個對象,將Props掛載到super上。

class App extends React.Component {
 constructor (props) {  super(props)  this.state = {  }  }  // render函數  render () {  return (  <div className="App">  <p>我是Class組件</p>  </div>  )  } } 複製代碼

Function組件

隨着React Hooks發佈,開發的主流也漸漸的轉入了函數組件,不過Class組件在舊項目中仍是會用的。因此都學習一下。對比Class組件,函數組件就很是的簡單了。在函數內部返回一個render模板就OK了。以下:

import React from 'react'
 function FunctionDemo () {  return (  <div>  我是函數組件  </div>  ) }  export default FunctionDemo 複製代碼

Class組件State狀態

這裏着重的開個單章,主要是Class組件中的State值更改,由於函數組件最好使用的是hooks,因此單拎出來主要解一下Class組件下State狀態。在React不建議直接修改State的值,而是使用setState的方式更新狀態。

this.setState({
 default: '修改後的文件' }) 複製代碼

一樣的,setState後當前的值並不會直接改變。它是一個異步函數,在異步函數中能夠拿到最新的狀態。

若是須要進行計算值的累加,推薦使用的是經過函數的返回值形式。

這裏的原理相似Vue的組件data的函數return方式。 若是使用對象方式的話,在多個setState使用的話會被後面的任務覆蓋,從而直接執行一次

- - QAQ
// no
this.setState({ index: this.state.index + 1 }); this.setState({ index: this.state.index + 1 });  // yes this.setState({ index: this.state.index + 1 });  this.setState({ index: this.state.index + 1 }); this.setState((prevState, props) => {  return {quantity: prevState.quantity + 1}; }); 複製代碼

組件通訊

組件通訊是開發中常常用到的功能,可謂是靈魂之一了。那麼React的組件通訊是如何完成的呢?

子組件獲取父組件的值 Props

經過Props可使子組件很是快捷的拿到父組件的傳遞過去的內容。

  • 1.在子組件上添加屬性名稱和數據
<ClassDemo name="wangly19"></ClassDemo>
複製代碼
  • 2.在Class中使用Props
constructor (props) {
 super(props)  this.state = {  defaultText: '我是默認的文字'  } } 複製代碼
  • 3.使用

經過this.props.父組件綁定的屬性名稱

<p>{ this.props.name }</p> 複製代碼

定義默認的Props屬性

Vue中能夠定義Props的默認值,哪怕用戶沒有傳遞,就會顯示默認Props中定義的內容。

ClassDemo.defaultProps = {
 name: '我是默認的名稱'  // ... 參數列表 } 複製代碼

子組件傳遞父組件

經過Props傳遞一個函數,當子組件須要改變父組件的值時,經過this.props.[函數]執行回調。

// 父組件
class App extends React.Component {  constructor (props) {  super(props)  this.state = {  childMessage: '2222222222222222'  }  }   onPropChange (newVal) {  this.setState({  childMessage: newVal  })  }   render () {  return (  <div className="App">  <p>{ this.state.childMessage }</p>  <ClassDemo onPropChange={ this.onPropChange.bind(this) }></ClassDemo>  {/* <FunctionDemo></FunctionDemo> */}  </div>  )  } } 複製代碼
import React from 'react';
 class ClassDemo extends React.Component {  constructor (props) {  super(props)  this.state = {  defaultText: '我是默認的文字'  }  }   changeText () {  this.props.onPropChange('111111111111111')  }   render () {  return (  <div className="App">  <button onClick={ this.changeText.bind(this) }>更改文本</button>  </div>  )  } } export default ClassDemo; 複製代碼
圖

生命週期

看了官方的生命週期介紹,挺簡潔的。分別是組件模板選而後,已經準備就緒的時候,能夠作組件加載後的一些邏輯操做,鎮樓神圖。

鎮樓神圖
鎮樓神圖

掛載

constructor

構造函數初始化,最早被執行,初始化State等等。

getDerivedStateFromProps

這是一個靜態方法,須要在前面增長static的屬性

render

渲染函數,返回渲染的內容,當頁面產生更新也會觸發該方法。

componentDidMount

組件掛載以後,這個時候組件已經掛載完畢了

更新

getDerivedStateFromProps

組件即將被更新,這裏參數分別對應先後被修改的內容,經過返回一個布爾值告知是否須要更新視圖。

render

當視圖更新,那麼Render也會從新更新

getSnapshotBeforeUpdate

getSnapshotBeforeUpdaterender以後componentDidUpdate以前輸出,相似於中間件用來作一些捕獲操做。

componentDidUpdate

getSnapshotBeforeUpdate,有三個參數prevPropsprevStatesnapshot,表示以前的props,以前的state,和snapshotsnapshotgetSnapshotBeforeUpdate返回的值

constructor (props) {
 super(props)  this.state = {}  console.log('1.constructor構造函數') }  componentDidMount () {  console.log('componentDidMount')  Store.subscribe(() => {  this.setState({})  }) }  static getDerivedStateFromProps (nextProps, prevState) {  console.log('getDerivedStateFromProps')  console.log(nextProps, prevState)  return true }  getSnapshotBeforeUpdate (prevProps, prevState) {  console.log(prevProps, prevState)  return 'top: 200' }  componentDidUpdate (prevProps, prevState, snapshot) {  console.log(prevProps, prevState, snapshot) }  componentWillUnmount () {  console.log('componentWillUnmount') }  changeText () {  Store.dispatch({  type: 'changeName',  value: '我是ClassDemo中修改的名字: wangly'  }) }  render () {  console.log('3.render函數')  return (  <div className="App">  <p>{ Store.getState().redux_name }</p>  { this.state.redux_name }  <button onClick={ this.changeText.bind(this) }>更改文本</button>  </div>  ) } 複製代碼

卸載

componentWillUnmount

組件卸載,咱們能夠清除一些定時器,取消網絡請求。

組件插槽

插槽對於Vue來講並非很陌生,在React中插入的節點會以Props的方式傳遞。能夠經過pro1ps.children找到而且渲染出來。

// 父親組件
<ClassDemo onPropChange={this.onPropChange.bind(this)}>  <h1>插入的元素 </h1> </ClassDemo>  // 子組件 <div className="App">  {this.props.children}  <button onClick={this.changeText.bind(this)}>更改文本</button> </div> 複製代碼

Router路由

路由對於SPA應用來說可謂是重中之重,沒有它的話,那麼這個頁面也就不能成爲應用,只能稱之爲頁面。二者可謂天差地別。

安裝react-router-dom --save

# shell
npm install react-router-dom --save 複製代碼

建立路由模式

在Vue中都知道路由的mode有兩種,一種是hash一種是history模式。分別以下,經過引入不一樣的包來建立不一樣的Router

// histoty import { BrowserRouter as Router, Link, Route } from 'react-router-dom'; // hash import { Link, Route, HashRouter as Router } from 'react-router-dom'; 複製代碼

建立一個簡單的路由

經過as出來的Router包裹路由快,經過Link做爲跳轉的行爲容器。這樣一個基本的路由容器就完成。

須要經過使Route進行對組件的聲明配置,才能被Link找到哦。

- - QAQ
import React from 'react';
// histoty import { BrowserRouter as Router, Link, Route } from 'react-router-dom'; // hash // import { Link, Route, HashRouter as Router } from 'react-router-dom';  function Page1 () {  return (  <h1>我是Page1</h1>  ) }  function Page2 () {  return (  <h1>我是Page2</h1>  ) }  function Page3 () {  return (  <h1>我是Page3</h1>  ) }  class App extends React.Component {  constructor (props) {  super(props)  this.state = {  }  }   render () {  return (  <div className="App">  <Router>  <ul>  <li>  <Link to="page1">Page1</Link>  </li>  <li>  <Link to="page2">Page2</Link>  </li>  <li>  <Link to="page3">Page3</Link>  </li>  </ul>  <Route exact path="/page1" component={ Page1 }></Route>  <Route exact path="/page2" component={ Page2 }></Route>  <Route exact path="/page3" component={ Page3 }></Route>  </Router>  </div>  )  } } export default App; 複製代碼

路由傳值

路由傳遞參數通常使用paramquery參數。經過給to傳遞一個對象的方式來進行數據的傳遞。能夠看到,向page1的路由上添加了一個:id表示須要傳遞paramid的值,同時聲明瞭search的文本和state對象多種方式傳遞了參數。以便根據不一樣的場景使用。

;<div className="App">  <Router>  <ul>  <li>  <Link  to={{  pathname: '/page1/10',  search: '?roles=[10, 20]',  state: { name: 'wangly19' },  }}  >  Page1  </Link>  </li>  <li>  <Link to="page2">Page2</Link>  </li>  <li>  <Link to="page3">Page3</Link>  </li>  </ul>  <Route exact path="/page1/:id" component={Page1}></Route>  <Route exact path="/page2" component={Page2}></Route>  <Route exact path="/page3" component={Page3}></Route>  </Router> </div>  複製代碼

手動跳轉

當你使用History路由的時候,某些時候須要主動的跳轉道某個路由,這個時候又不能去觸發節點行爲,因此這個時候就能夠經過API的方式,進行跳轉。使用方式和Vue大差不差。

// 跳轉頁面
this.props.history.push(參數和to的內容像素) this.props.history.push('page1')  // 重定向頁面 this.props.history.replace('page2') 複製代碼

固然還有hashgo方法。

Redux狀態管理

Redux是相似於Vuex的一個全局狀態解決方案,它的功能主要是用來存儲公有全局狀態。來方便管理一些共有配置參數,解決業務體積大,結構複雜的項目提供好的狀態管理。

若是項目不是特別須要,儘可能不去使用它。

- - QAQ

安裝Redux

# shell
npm install redux --save 複製代碼

建立Store State

看到官方的Demo,是很是容易懂的。下面是官方的代碼,一眼就能看出流程。

靈魂手繪
靈魂手繪
import { createStore } from 'redux'
 /**  * This is a reducer, a pure function with (state, action) => state signature.  * It describes how an action transforms the state into the next state.  *  * The shape of the state is up to you: it can be a primitive, an array, an object,  * or even an Immutable.js data structure. The only important part is that you should  * not mutate the state object, but return a new object if the state changes.  *  * In this example, we use a `switch` statement and strings, but you can use a helper that  * follows a different convention (such as function maps) if it makes sense for your  * project.  */ function counter(state = 0, action) {  switch (action.type) {  case 'INCREMENT':  return state + 1  case 'DECREMENT':  return state - 1  default:  return state  } }  // Create a Redux store holding the state of your app. // Its API is { subscribe, dispatch, getState }. let store = createStore(counter)  // You can use subscribe() to update the UI in response to state changes. // Normally you'd use a view binding library (e.g. React Redux) rather than subscribe() directly. // However it can also be handy to persist the current state in the localStorage.  store.subscribe(() => console.log(store.getState()))  // The only way to mutate the internal state is to dispatch an action. // The actions can be serialized, logged or stored and later replayed. store.dispatch({ type: 'INCREMENT' }) // 1 store.dispatch({ type: 'INCREMENT' }) // 2 store.dispatch({ type: 'DECREMENT' }) // 1 複製代碼
  • 建立Stoge
// 聲明默認的State狀態值
const modeStore = {  redux_name: '我是Redux中聲明的名稱:wangly19' } // 聲明Reducer const reducer = (state = modeStore, action) => {  return state } // createStore import { createStore } from 'redux'; import reducer from './reducer' const store = createStore(reducer) export default store 複製代碼
  • 視圖渲染
import Store from './index'
<p>{ Store.getState().redux_name }</p> 複製代碼
  • 觸發更新行爲dispatch
<button onClick={ this.changeText.bind(this) }>更改文本</button>  // dispatch changeText () {  Store.dispatch({  type: 'changeName',  value: '我是ClassDemo中修改的名字: wangly'  }) } 複製代碼

前提是,須要對action的方法作一個聲明。相似於Vuex的Action

const reducer = (state = modeStore, action) => {
 switch (action.type) {  case 'changeName':  const newState = {...state}  console.log(state)  newState.redux_name = action.value  console.log(newState)  console.log(state)  return newState   default:  return state;  } } 複製代碼
  • 監聽變化。

做爲行爲觸發行爲後更新視圖的憑證。在組件註銷時,注意銷燬它哦。

- - QAQ
componentDidMount () {
 /**  * 回調函數  */  Store.subscribe(() => {  console.log(Store.getState().redux_name)  this.setState({})  }) } 複製代碼

Hooks

Hooks我準備寫新的文章。

- - QAQ

總結

學習React不少都是以Vue的思路先入個門,不至於一問三不知。也明白了知其一而知其三。若是有基礎那麼學習起來其實並非很困難。可是它的文檔並不如Vue的全面,且對於某些方面來講。花了一天時間整理一些基本的學習東西

若是以爲對你有幫助,不妨點個贊哦。

- - QAQ

參考資料

React文檔

react生命週期我的理解

react模板

React路由

Redux

相關文章
相關標籤/搜索