react组件基础知识点及事例

128 阅读5分钟

本文已参与[新人创作礼]活动,一起开启掘金创作之路

一.前言

这里默认你已经安装了react的环境准备,没有去官网

zh-hans.reactjs.org/docs/gettin…

可以先了解下JSX

juejin.cn/post/709356…

二.组件

1.基本介绍

  • 组件是React中最基本的内容,使用React就是在使用组件
  • 组件表示页面中的部分功能
  • 多个组件可以实现完整的页面功能
  • 组件特点:可复用,独立,可组合

2.React创建组件的两种方式

(1)函数组件

是什么

使用JS的函数或者箭头函数创建的组件

要求

  • 为了区分普通标签,函数组件的名称必须大写字母开头
  • 函数组件必须有返回值,表示该组件的结构
  • 如果返回值为null,表示不渲染任何内容

怎么用

/0 准备工作(类组件也许准备)

index.js

import App from './App';
root.render(
    <App />
);
/1 箭头函数

App.js

import React from 'react'
const App=()=>{
  return <div>666</div>
}
export default App
/2 函数

App.js

import React from 'react'
 function App() {
   return <div>666</div>
}
export default App

(2)类组件

了解

此处应有链接

是什么

使用ES6的class语法创建组件

要求

    1. 类名必须以大写字母开头
    1. extends是一个关键字,用来实现类之间的继承。类组件应该继承 React.Component 父类,从而使用父类中提供的方法或属性。
    1. 类组件必须提供 render 方法,render 方法必须有返回值,表示该组件的 UI 结构。render会在组件创建时执行一次

怎么用

import React from 'react'

class Com extends React.Component {
  render() {
    return 
<div>
</div>
  }
}
export default Com

3.提取组件(举例)

src\views\Class.js

import React from 'react'

class Class1 extends React.Component{
  render(){
    return (
    <div>
       Class
    </div>
    )
  }
}
export default Class1

src\views\Hello.js

import React from 'react'

class Hello extends React.Component{
  render(){
    return (      
  <div>
   Hello
    </div>
    )
  }
}
export default Hello

src\App.js

import React from 'react'
import Hello from './views/Hello'
import Class1  from './views/Class'

class Com extends React.Component {
  state={
    sMsg:''
  }
  fatherFn=(msg)=>{
    this.setState({
     sMsg:msg 
    })
    console.log('father',msg);
  }
  render() {
    return <div>
      App
      <hr/>
      <Hello/>
      <hr/>
      <Class1/>
  </div>
  }
}
export default Com

效果

image.png

4.存放数据的两种方式

(1)

  constructor(){
    super()
    this.state={
      name:666
    }
  }
	

了解

首先说一点,ES5和ES6的继承机制不同,ES5的继承实质是通过,先创建子类的实例this,
然后再将父类的方法添加到子类实例this上面,也就是说,ES5中,每一个实例是有自己的
this的,而到了ES6中,继承机制变成了,先创建父类的实例this,然后子类去修改父类的
this实现继承,因此要想在ES6中实现继承,需要使用super去引用父类的构造函数,返回
子类实例即 super 内部的 this 指的是 B,因此 super() 在这里相当于`A.prototype.constructor.call(this, props)`。
但是,如果不使用constructor,组件无法使用state,打印的state始终都是null,
也就是说,如果使用无state组件,可以不使用constructor,只通过props来接收值
(这个时候就建议使用无状态组件了),这种主要作用是模板,和只接收父元素的值得情况;
如果要用state,需要把this. state写到constructor里面,

(2)

   state={
    name:666
   },
在react中,如果没有显式的去定义constructor方法,在执行的时候,constructor也会被
添加,这样一来,任何一个子组件无论有没有显式的定义,都有constructor方法,因此constructor
方法的定义并不是必须的。

变量不可以放空值,未定义的话赋值null

5.改值

import React from 'react'

class Class1 extends React.Component{
  state={
    name:666
  }
  fn=()=>{
    this.setState({
      name:this.state.name+1
    })
      console.log(this.state.name);
  }

  render(){
    return (
    <div>
      类组件==={this.state.name}
      <button onClick={this.fn}>+1</button>
    </div>
    )
  }
}
export default Class1	

  • 不可以num++因为变量名后面++先获取后赋值,数据相当于慢一次

  • log获取到的慢一次,因为改state属于异步操作后执行

  • 箭头函数里调用this指向外部环境

  • 若不使用箭头函数而使用函数

     方法1
     <div>
     类组件==={this.state.name}
     <button onClick={this.fn.bind(this)}>+1</button>
     </div>
    
     方法2
     constructor(){
     super()
     this.fn=this.fn.bind(this)
      }
    
     方法3(常用)
     <button onClick={()=>this.fn()}>+1</button>
    

6.受控组件(常用)

是什么

 value值受到了react控制的表单元素
 

怎么做

  • 根据表单元素类型获取对应的值
  • 在事件处理程序修改对应的state
import React from 'react'

class Hello extends React.Component{
  state={
    desc:'帅锅'
  }
  ff=(e)=>{
    this.setState({
      desc:e.target.value
    })
  }
  render(){
    return (      
  <div>
    <br/>
      描述:
      <textarea
      name='desc'
       onChange={this.ff}
       value={this.state.desc}
      ></textarea>==={this.state.desc}
      <br/>
    </div>
    )
  }
}
export default Hello

7.非受控组件

是什么

非受控组件借助于ref,使用原生DOM的方式来获取表单元素的值

怎么用

  • 调用React.createRef()方法创建一个ref
    
  • ref对象添加到对应文本框中
    
  • 通过ref对象获取文本框的值并修改state中的值
    
import React from 'react'

class Hello extends React.Component{
  state={
    val2:'true'
  }
  txt=React.createRef()
  fff=()=>{
     console.log(this.txt.current.value,8);
     this.setState({
       val2:this.txt.current.value
     })
  }
  render(){
    return (      
  <div>
      单身:
      <input 
      type='text'
       onChange={this.fff}
       ref={this.txt}
      ></input>==={this.state.val2}
    </div>
    )
  }
}
export default Hello

8.综合案例

import React from 'react'
class Hello extends React.Component {
  state = {
    list: [
      { id: 1, name: '水浒传' },
      { id: 2, name: '西游记' },
      { id: 3, name: '红楼梦' },
    ],
    val: '',
    vv:'添加',
    setId:0,
  }
  Books=(e)=>{
    this.setState({
      val:e.target.value,
      id:this.state.list.length+1
    })
  }
  addBooks = () => {
    if(this.state.vv==='编辑'){
      let list = this.state.list
      list[this.state.setId].name=this.state.val
      this.setState({
        vv:'添加',
        list,
        val:''
      })
    }else{
      console.log('2');
       this.state.list.push(
      {name:this.state.val,
    id:this.state.list.length+1
        })
    this.setState({
      list:this.state.list
    })
    }

  }
  delBooks=(id)=>{
    console.log(id);
    this.setState({
      list:this.state.list.filter(item=>item.id!==id)
    })
  }
  setBooks(item,index){
    this.setState({
      vv:'编辑',
      setId:index,
      val:item.name
    })
  }
  render() {
    return (
      <div>
        ===Todo===
        <input
          type="text"
          value={this.state.val}
          onChange={this.Books}
        />==={this.state.val}
        <button onClick={this.addBooks}>{this.state.vv}</button>
        <ul>
          {this.state.list.map((item,index) => (
            <li key={item.id}>
              标号:{item.id}===书名:{item.name}====
              <button onClick={()=>this.delBooks(item.id)}>删除</button>
              {/* 函数的话不加括号立即执行 */}
              ===<button 
              onClick={()=>this.setBooks(item,index)}>编辑</button>
            </li>
          ))}
        </ul>
      </div>
    )
  }
}
export default Hello

三.组件间传值

0.父

import React from 'react'
import Son2 from './props/son2'
import Son from './props/son'
class Com extends React.Component {
  state={
    sMsg:'1'
  }
  fatherFn=(msg)=>{
    this.setState({
     sMsg:msg 
    })
    console.log('father',msg);
  }
  render() {
    return <div>
     <Son ff={this.fatherFn}></Son>
      <Son2 f={this.state.sMsg}></Son2>
  </div>
  }
}
export default Com

1.父传子

src\props\son2.js

import React from 'react'

const Func = (props) => {
  let fn=(i)=>{
    console.log(i);
  }
  return <div>
    <button onClick={()=>fn(props.f)}>son22</button>
    <h1>{props.f}</h1>
</div>
};
export default Func

2.子传父

src\props\son.js

import React from 'react'

class Com extends React.Component {
  f=()=>{
    this.props.ff('1')
  }
  render() {
    return <div>
      <button onClick={this.f}>son1</button>
      <button onClick={()=>this.props.ff('我传的')}>son11</button>
    </div>
  }
}
export default Com

3.后代传值

(1)获取react内置组件

src\context

import React from 'react'
const { Provider , Consumer } = React.creatContext()
export { Provider , Consumer  }

注:不建议用export default因为{}会被解析为export会出报错eslint报错

(2)爷爷

App.js

import { Provider } from './context'
import Son from './props/son'
  ...
render(){
  return (
    <Provider value=传的值>
    
    <Son></Son>
    
    </Provider>   
  )
}

(3)儿子

import Sun from './sun'
render(){
 return(
  <sun></sun>
 )
}

(4)孙子

import { Consumer } from './context'
...
return <Consumer>{(data)=><span>{data}</span>}</Consumer>//即可获取到爷爷传过来的值