react入門學習及總結


前言

不知不覺一年又過去了,新的一年又到來,2019應該要好好思考,好好學點有用的東西,規划下自己今后的學習方向,不要再像以前那樣感覺很迷茫。

react簡單介紹

官網及中文文檔
https://reactjs.org
https://github.com/facebook/react
https://react.docschina.org/

和vue一樣,react是一個用於構建用戶界面的 JavaScript 庫,起初只是Facebook的一個內部項目,用來架設 Instagram 的網站,后於2013年5月開源

特點
1、使用 JSX語法 創建組件,實現組件化開發,為函數式的 UI 編程方式打開了大門
2、性能高的讓人稱贊:通過 diff算法 和 虛擬DOM 實現視圖的高效更新

核心概念
1、虛擬DOM(Virtual DOM)
2、Diff算法(虛擬DOM的加速器,提升React性能的法寶)

create-react-app安裝

像vue-cli一樣,官方為我們提供了一個create-react-app腳手架,通過腳手架安裝,無需再配置webpack相關東西。
詳情可以查看create-react-app文檔

全局安裝
npm install -g create-react-app
創建項目
create-react-app hello-react

創建完成之后
cd hello-react
npm start
接着我們就可以通過瀏覽器訪問
http://localhost:3000/

項目生成后,默認目錄結構包含
public和src兩個文件夾 ,其中public里的index.html是整個項目的首頁,最終所有的組件內容會掛載到這個頁面中;
src下面就是我們編寫組件的地方,默認里面有index.js文件,是一個入口文件

除了npm start命令之外

默認還為我們提供了以下命令
npm run build 用於生產環境編譯打包
npm test 測試
npm run eject 這個是用來顯示默認的配置文件,實現自定義的配置修改,如webpack相關的配置,這個命令屬於單向操作,一旦使用,就不能恢復了。

第一個react程序

class HelloMessage extends React.Component {
  render() {
    return (
      <div>
        Hello {this.props.name}
      </div>
    );
  }
}

ReactDOM.render(
  <HelloMessage name="Taylor" />,
  mountNode
);

上面這段代碼就是react的基本寫法,使用的是jsx語法,跟vue區別挺大的,推崇用js的方式去編寫html和樣式。

下面簡單對react組件的用法做一下演示

我們在src目錄下建立一個components文件夾

並創建c1,c2,c3三個js文件

我們在入口文件index.js中添加以下內容

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import C1 from './components/C1.js';
import C2 from './components/C2.js';
ReactDOM.render(
	<div>
		<C1/><App /><C2/>
	</div>
	, document.getElementById('root'));

在c1.js文件中復制下面的代碼

import React, { Component } from 'react';
import './C1.css';
class C1 extends Component {
 render() {
  return (
     <div className="c1">
    c1
     </div>
     );
 }
}
export default C1;

c2.js一樣,也是添加以上代碼,修改對應的名字就行。

然后在app.js中添加如下代碼

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import C3 from './components/C3.js';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          hello
        </header>
        <C3/>
      </div>
    );
  }
}

export default App;

可與看到我們在app.js中使用了c3組件,這里屬於是一個嵌套組件,因為app.js也是一個組件在
index.js中使用

最終的效果就是c1,c2,app及app嵌套組件c3中的內容按照順序被展示出來了

通過以上內容,我們大致熟悉了react中組件的寫法方式,接下來我們來做一個todolist小項目

todolist項目

image

我們還是使用create-react-app來創建一個名為todolist-react的項目
在src下面建立components文件夾,並添加
appform,applist,apptabs,apptodos這四個js文件,index.js依然作為我們的項目入口文件

添加以下幾條默認數據傳遞到App容器組件中

let data = [
 {id: 0, text: '吃飯唱歌打豆豆1', complete: false},
 {id: 1, text: '吃飯唱歌打豆豆2', complete: false},
 {id: 2, text: '吃飯唱歌打豆豆3', complete: true},
]

ReactDOM.render(<App data={data}/>, document.getElementById('root'));

在app.js文件中

state = {
      choosevalue : 1,//篩選 1全部 2未完成 3已完成
      data: this.props.data
  }

state作為數據管理,添加data熟悉並使用this.props.data獲取到父組件data列表數據

在render函數中通過data屬性傳入到applist組件中

render() {
    const { data } = this.state; 
    return (
      <div className="App">
        <AppForm 
          AddTodoItem={this.OnAddTodoItem.bind(this)} />

        <AppTabs SubmitChooseValue={this.ChooseValue.bind(this)}/>
        <AppList 
          data={this.state.data}
          choosevalue={this.state.choosevalue} 
          ChangeCompleteTop={this.AllChangeComplete.bind(this)}
          DeleteItemTop={this.AllOnDeleteItem.bind(this)}/>
      </div>
    );
  }

然后,在我們的applist中對data進行遍歷將值賦給每一個item項,AppTodos作為嵌套組件將id, text, complete以及index值傳遞過去

{this.props.data.map(({ id, text, complete }, index) => (
      		<AppTodos 
	               key={index} 
	               id={id} 
	               text={text} 
	               complete={complete}/>
        ))}

appform組件用來對用戶輸入進行添加到待辦事項中

<form className='ui reply form'
		onSubmit={this.handleSubmit.bind(this)}>
        <div className='field' style={styles.title}>
          <input type='text' placeholder='TODO' ref='text' />
        </div>

        <button type='submit' className='ui blue button'>
            添加
        </button>
      </form>

當用戶點擊添加時候會觸發onSubmit事件,通過this.refs.text.value獲取到用戶輸入的值后調用父組件AddTodoItem函數並將新數據加入到列表中

handleSubmit (event) {
	    event.preventDefault()
	    let text = this.refs.text.value
	    
	    if (!text.trim()) {
	      alert("Input can't be null")
	      return
	    }
	    
	    let id = uuid();
	    this.props.AddTodoItem({id,text,complete:false});
  }

app.js文件中監聽OnAddTodoItem事件

// 合並data,並更新state
  OnAddTodoItem (newItem) {
    let newdata = this.state.data.concat(newItem);
    this.setState({data : newdata});
  }

這樣我們添加的數據就會直接顯示在列表中了

其他的功能,還有諸如數據過濾,全部、完成、未完成
狀態修改及刪除

由於時間關系,而且代碼本身也比較簡單,直接看代碼也能看的懂,剩余部分功能代碼我上傳到github上面,可以直接fork下來閱讀,或者跟着代碼寫一遍

todolist-react項目地址

react父子組件通信

在項目中我們的app.js和appform.js。app.js作為父組件,這里涉及到父子組件通信

1、app.js添加OnAddTodoItem函數
用於合並data,並更新state

  OnAddTodoItem (newItem) {
    let newdata = this.state.data.concat(newItem);
    this.setState({data : newdata});
  }

2、在AppForm組件標簽添加AddTodoItem函數bind指向OnAddTodoItem

  <AppForm 
          AddTodoItem={this.OnAddTodoItem.bind(this)} />

3、form.js子組件中通過props觸發AddTodoItem函數

this.props.AddTodoItem({id,text,complete:false});

jxs語法樣式對象聲明

styles樣式對象聲明是jxs語法中聲明樣式的一種方式,也可以通過className來添加樣式

var styles = {
  'title': {
    width: 200,
    display: 'inline-block',
    marginRight: 10,
    verticalAlign: 'top'
  }
}


<div className='field' style={styles.title}>
          <input type='text' placeholder='TODO' ref='text' />
        </div>

refs獲取表單值

使用this.refs.all.value可以直接拿到表單中的value值, 前提需要在表單中設定ref的值ref='all'

handleAll () {
	    let all = this.refs.all.value;
	    this.props.SubmitChooseValue(all);
	}
	
	
	<button 
           type='submit' 
           style={styles.top} 
           className='ui blue button' 
           value='1' 
           ref='all'
           onClick={this.handleAll.bind(this)}
         > 

數組遍歷顯示列表

我們可以直接在return中編寫遍歷語句,使用{}大括號包住

render() {

	// 通過不同的choosevalue值 過濾list內容
	var value = this.props.choosevalue;
	// alert(value)

    return (
      <div>
      	{this.props.data.map(({ id, text, complete }, index) => (
      		<AppTodos 
	               key={index} 
	               id={id} 
	               text={text} 
	               complete={complete}/>
        ))}
      </div>
    )
 }

除了以上這種方式,也可以這樣

在return之外進行遍歷,然后返回一個參數,將返回參數添加到return中即可

	render() {

	// 通過不同的choosevalue值 過濾list內容
	var value = this.props.choosevalue;
	// alert(value)
	var list = this.props.data.map(({ id, text, complete }, index) => {
		return <AppTodos 
               key={index} 
               id={id} 
               text={text} 
               complete={complete}/>
	})
    return (
      <div>{list}</div>
    )
}

其實jsx本身其實也是一種表達式,在編譯之后,JSX 其實會被轉化為普通的 JavaScript 對象。
意味着,我們可以在 if 或者 for 語句里使用 JSX,將它賦值給變量,當作參數傳入,作為返回值都可以

function getGreeting(user) {
  if (user) {
    return <h1>Hello, {formatName(user)}!</h1>;
  }
  return <h1>Hello, Stranger.</h1>;
}

最后

以上就是簡單了解對react的使用,然后做了一個todolist小demo,涉及到了父子組件通信,因為只有2層,所以使用props完全就可以,沒有任何問題,但是假如項目更加復雜,涉及組件比較多,父子組件通信,子組件與子組件通信,我們就需要引入redux來做數據的狀態管理了 ,類似vue中的vuex一樣。之后,進一步學習react,對react的生命周期和router路由以及redux狀態管理做一個了解和學習使用

參考閱讀

http://caibaojian.com/react/
react新手demo——TodoList
來自一位react新手的react入門須知
阮一峰react教程
React入門看這篇就夠了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM