React -- 簡易項目實戰


參考文獻

一、創建項目

npx create-react-app myTest

創建完成后,項目下面主要有publicsrc文件,前者是用來存放靜態資源文件的,其中最主要的就是index.html文件,后者則是用來存放所有的react代碼的
項目搭建好后,切換進項目,執行npm start命令,即可在本地localhost:3000窗口打開項目

二、修改app.js

運行完成后,我們可以頁面看見效果
打開src文件夾,里面有個index.js和app.js文件,其中index.js是主入口文件,app.js就是頁面展示建議react組件,現在修改一下app.js里面的東西,寫入Hello React !,然后保存看看頁面
書寫代碼有jsx和非jsx語法兩種格式:
jsx

const h1 = <h1 class="app-title">Hello React !</h1>

no-jsx

const h1 = React.createElement('h1', {className: 'app-title'}, 'Hello React !')

三、創建Table.js

現在新建一個table.js文件,來設計一個表格組件,並將這個組件添加到app.js組件中
新建組件注意事項
1、Component作為一個組件引入了,不需要再執行React.Component
2、使用class繼承,元素必須在render()方法里面返回
3、樣式類名書寫是className,不是class
4、一定要將組件導出export default componentName
5、react組件名必須大寫字母開頭
6、只能return一個根元素,不能return兩個根元素,也就是說renturn的標簽必須包裹在一個根標簽里面,不能是兩個同級標簽

import React, { Component } from 'react'

class Table extends Component {
  render() {
    return (
      <table>
        <thead>
          <tr>
            <td>Name</td>
            <td>Job</td>
          </tr>
        </thead>
        <tbody>
          <tr>
            <td>李狗蛋</td>
            <td>程序猿</td>
          </tr>
          <tr>
            <td>王翠花</td>
            <td>攻城獅</td>
          </tr>
        </tbody>
      </table>
    )
  }
}
export default Table

組件寫好后,在app.js里面引入組件並使用

import Table from './table.js'

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <h4>Hello React !</h4>
        <Table />
      </header>
    </div>
  );
}

然后保存查看頁面

看起來樣子有些丑,然后創建一個table.css文件,書寫一些樣式,讓table美觀一下,然后在table.js頁面引入css文件

import './table.css'

然后保存查看頁面

四、簡單組件

其實通過class創建的組件可以稱之為復雜組件,還可以創建簡單組件,所謂的簡單組件,其實用類似函數的方式聲明組件,現在用簡單組件把table的頭部和軀體部分分別分離出來作為一個單獨的小組件
簡單組件跟復雜組件的區別之一就是簡單組件不需要render()方法去置換一下return元素,直接返回react元素

// table.js
function TableHead(props) {
  return (
    <thead>
      <tr>
        <th>Name</th>
        <th>Job</th>
      </tr>
    </thead>
  )
}

function TableBody(props) {
  return (
    <tbody>
      <tr>
        <td>李狗蛋</td>
        <td>程序猿</td>
      </tr>
      <tr>
        <td>王翠花</td>
        <td>攻城獅</td>
      </tr>
    </tbody>
  )
}

調用

class Table extends Component {
  render() {
    return (
      <table>
        <TableHead />
        <TableBody />
      </table>
    )
  }
}

保存查看頁面,發現頁面並沒有什么變化,是一樣的

所以所有組件都是可以相互嵌套的,而且簡單組件和復雜組件也是可以相互嵌套的,並沒有的區別

五、組件通信props

react中組件通信跟vue有點類似,是通過props來接收數據傳遞,不同的是:
1、數據是全局保存在props對象里面的,直接調用props對象就可以獲取
2、數據傳遞也不需要通過v-bind來綁定參數,直接寫即可,只不過傳入參數使用{}包裹,而不是""
3、在簡單函數里,props是作為一個參數傳入的,所以直接通過props.key獲取,但是在class里面,props是繼承於Compoent,需要通過super()方法,調用是通過this.props.key
因為所有組件都是在app.js里面渲染的,所以現在要在app.js里面創建數據傳遞過去,需要注意一點就是傳遞的數據必須創建在渲染組件元素的render()函數里面,創建在render()方法之外,是沒有效果的,如果是簡單組件,就直接聲明一個數據數組
數據聲明好之后,直接在組件上傳遞

function App() {
  const Head = [
    { header: 'Name' },
    {header: 'Job'}
  ]
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <h4>Hello React !</h4>
        // 傳遞數據
        <Table Head={Head} />
      </header>
    </div>
  );
}

接下來就可以在Table組件的render函數通過es6方法從props里面拿到數據賦值給新聲明的變量,注意必須在render()方法里面聲明獲取,簡單函數直接聲明獲取獲取

class Table extends Component {
  render() {
    // 拿取元素
    const {Head} = this.props
    return (
      <table>
        <TableHead Head={Head} />
        <TableBody />
      </table>
    )
  }
}

接下里就是列表渲染表格頭部了,注意react里面列表渲染時通過map()方法實現的,因為map()方法返回的是一個結果數組
需要注意的是每一個循環創建的react元素必須賦予一個key值,這是唯一標識符,同一個react元素里不能相同

const TableHead = (props) => {
  const myHead = props.Head.map((item, index) => {
    return <th key={index}>{item.header}</th>
  })
  return (
    <thead>
      <tr>
        {myHead}
      </tr>
    </thead>
  )
}

然后保存查看頁面,發現頁面結構數據並沒有變化,也沒有報錯

同理我們可以把body數據也可以賦予過去

const Body = [
    {
      name: '李狗蛋',
      job: '程序猿',
    },
    {
      name: '王翠花',
      job: '攻城獅',
    },
    {
      name: '二狗子',
      job: '加班狗',
    }
  ]
<Table Head={Head} Body={Body} />

弄好之后,保存查看頁面結果

六、數據修改state

通過props可以傳遞數據,但是這個數據傳過去后是不可變的,無法進行操作,所以需要通過state來聲明數據,這樣數據就可以通過this.setState()方法來進行相關操作
現在我們創建一個state對象,把先前的數據全部移到這個對象里面

const state = {
    Head: [
      { header: 'Name' },
      {header: 'Job'}
    ],
    Body: [
      {
        name: '李狗蛋',
        job: '程序猿',
      },
      {
        name: '王翠花',
        job: '攻城獅',
      },
      {
        name: '二狗子',
        job: '加班狗',
      }
    ]
  }

在Table組件依然是通過this.props獲取這個數據
現在我們需要操作這個數組,來進行數組的內容的添加和刪除,首先我們執行刪除操作,在app.js聲明一個刪除數據的方法,用來執行刪除,這個方法是根據index來刪除
刪除函數

removeTr = index => {
    const { Body } = this.state
    this.setState({
      Body: Body.filter((item, ind) => {
        return ind !== index
      })
    })
  }

弄好之后,把數據通過props傳遞過去,然后回到Table組件,在body里面新增一行,執行方法

function TableBody(props) {
  const myBody = props.Body.map((item, index) => {
    return <tr key={index}>
      <td>{item.name}</td>
      <td>{item.job}</td>
      <td>
        <button onClick={() => props.removeTr(index)}>Delete</button>
      </td>
  </tr>
  })
  return (
    <tbody>
      {myBody}
    </tbody>
  )
}

注意
這里踩了一個坑,通過事件執行方法時,一定要通過一個函數去執行props里傳過來的方法,否則好像會自動執行
這樣我們點擊刪除按鈕,就會將當前的數組索引作為參數傳過去,然后通過filter()方法過濾掉index相同的數組項,返回其他數組項,實現刪除效果

七、新增數據

在做邏輯操作之前,我們需要新建一個新增數據的表單組件
Form.js

import React, { Component } from 'react'

class Form extends Component {
  constructor(props) {
    super(props)
    // 初始化input的value值
    this.initValue = {
      name: '',
      job: '',
    }
    // 將初始化值賦值給state
    this.state = this.initValue
  }
  // input標簽內容改變時執行
  handleChange = (e) => {
    this.setState({
      [e.target.name]: e.target.value,
    })
  }
  // 點擊提交按鈕時執行的操作
  submitForm = () => {
    // 這個方法是app.js那邊傳過來的,這個需要把用戶輸入的數據傳過去
    this.props.handleSubmit(this.state)
    // 重置input的value值
    this.setState(this.initValue)
  }
  render() {
    const {name, job} = this.state
    return (
      <form>
        <label>
          Name:
        </label>
        <input type="text" value={name} name="name" onChange={this.handleChange} /><br />
        <label>
          Job:
        </label>
        <input type="text" value={job} name="job" onChange={this.handleChange} /><br />
        <input type="button" value="新增" onClick={this.submitForm} />
      </form>
    )
  }
  }

app.js

handleSubmit = (valObj) => {
    // 通過解構的方式,把傳過來的數據添加到Body數組里,
    this.setState({
      Body: [...this.state.Body, valObj]
    })
  }


免責聲明!

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



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