React - Simple project combat

references

First, create a project

npx create-react-app myTest

Once created, the project has the following main publicand srcdocuments, the former is used to store static resource files, which is the most important index.htmldocument, which is used to store all react the code of
the project to build a good after switching into the project, the implementation of npm startcommand, you can at the local localhost:3000open the project window

Second, modify app.js

After the run is completed, we can see the results page
to open the src folder, which has a index.js and app.js file, which is the main entrance index.js file, app.js page display is recommended react components, now change it app. js stuff inside, write Hello React !, and then save the page to see
the writing code has jsx and non jsx grammar in two formats:
jsx

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

no-jsx

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

Third, create Table.js

Now create a new table.jsfile, to design a table component, and add this component to app.jscomponent in
the new assembly Note
1, Componentas a component introduced, do not need to perform React.Component
2, class inheritance, the element must render()return inside the method
3, style writing class name is className, not a class
4, be sure to export the components export default componentName
5, react component name must start with a capital letter
6, can only return a root element, can not return two root elements, that is to say renturn label must be wrapped in a root tag which can not be two similar labels

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

Written after assembly, which is introduced in the assembly and use 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>
  );
}

Then save view the page

looks like some ugly, and then create a table.css file, writing some style, so beautiful about the table, then the introduction of css files table.js page

import './table.css'

Then save the page view

Fourth, simple assembly

In fact, the component can be called by the class created complex components, you can also create a simple assembly, a so-called simple assembly, in fact, similar components function declaratively, and now the table with a simple assembly of the head and body portions are separated as a separate widget
simple assembly of complex components with one difference components do not need is a simple render () method to return about replacement elements, the elements react directly back

// 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>
  )
}

transfer

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

Save View page, find the page does not change, it is the same

so all components can all be nested with each other, but also simple components and complex assemblies can be nested in each other, and there is no difference

Fifth, the communication component props

react with the components of the communication VUE somewhat similar, is to receive data transmitted through the props, except that:
1, the data is stored in the global props inside the object, the object can be called directly acquire props
2, the data transfer need not v-bindbe tied to set parameters, you can write directly, but pass parameters to use {}package, instead of ""
3, in a simple function in, props is passed as a parameter, so directly through props.key, but in the class inside, props inherited in compoent, required by the super()method is invoked by this.props.key
passing in the past because all components are rendered in app.js inside, so now you want to create data in app.js inside, you need to pay attention to the data that is passed must be created in the rendering component elements render()inside the function, created in render()addition to the method, there is no effect, if it is simple component, directly declare an array of data
after good data declarations, passed directly on the component

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]
    })
  }

Guess you like

Origin www.cnblogs.com/zjh-study/p/10937847.html