React -- 简易项目实战

参考文献css

1、建立项目

npx create-react-app myTest

建立完成后,项目下面主要有publicsrc文件,前者是用来存放静态资源文件的,其中最主要的就是index.html文件,后者则是用来存放全部的react代码的
项目搭建好后,切换进项目,执行npm start命令,便可在本地localhost:3000窗口打开项目html

2、修改app.js

运行完成后,咱们能够页面看见效果
打开src文件夹,里面有个index.js和app.js文件,其中index.js是主入口文件,app.js就是页面展现建议react组件,如今修改一下app.js里面的东西,写入Hello React !,而后保存看看页面
书写代码有jsx和非jsx语法两种格式:
jsxvue

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

no-jsxreact

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

3、建立Table.js

如今新建一个table.js文件,来设计一个表格组件,并将这个组件添加到app.js组件中
新建组件注意事项
一、Component做为一个组件引入了,不须要再执行React.Component
二、使用class继承,元素必须在render()方法里面返回
三、样式类名书写是className,不是class
四、必定要将组件导出export default componentName
五、react组件名必须大写字母开头
六、只能return一个根元素,不能return两个根元素,也就是说renturn的标签必须包裹在一个根标签里面,不能是两个同级标签es6

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里面引入组件并使用npm

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'

而后保存查看页面
app

4、简单组件

其实经过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>
  )
}

调用this

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

保存查看页面,发现页面并无什么变化,是同样的

因此全部组件都是能够相互嵌套的,并且简单组件和复杂组件也是能够相互嵌套的,并无的区别

5、组件通讯props

react中组件通讯跟vue有点相似,是经过props来接收数据传递,不一样的是:
一、数据是全局保存在props对象里面的,直接调用props对象就能够获取
二、数据传递也不须要经过v-bind来绑定参数,直接写便可,只不过传入参数使用{}包裹,而不是""
三、在简单函数里,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} />

弄好以后,保存查看页面结果

6、数据修改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相同的数组项,返回其余数组项,实现删除效果

7、新增数据

在作逻辑操做以前,咱们须要新建一个新增数据的表单组件
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]
    })
  }
相关文章
相关标签/搜索