Appearance

「初学笔记」React(一)

WXL570CN2021/07/12beginner-notesReact

「初学笔记」React(一)

一、使用脚手架

npx create-react-app 项目名

二、组件的创建

1、函数创建

  • 函数名必须首字母大写
  • 必须返回组件的结构(结构使用jsx语法)
function Hello(){
  return (
    <div>Hello, React.</div>
  )
}

2、类创建

  • 类名必须大写
  • 继承父类React.Component
  • 类必须提供 render() 方法
  • render() 方法必须返回组件的结构(结构使用jsx语法)
class Hello extends React.Componnet {
  render () {
    return (
      <div>Hello, React.</div>
    )
  }
}
// 挂载到dom节点
ReactDom.render(<Hello />, root)

三、无状态组件和有状态组件

  • 函数组件 --> 无状态组件, 类组件 --> 有状态组件
  • 状态即数据

四、事件绑定

  • 语法:on + 事件名称 = {事件函数}
  • 驼峰命名

五、state(状态)

相当于Vue里面的data

class Hello extends React.Componnet {
  // constructor() {
  //   // 语法要求
  //   super()
  //   this.state = {
  //     msg: 'hello',
  //   }
  // }
  // 简化
  state = {
    msg: 'hello',
  }
}

setState()修改状态

class Hello extends React.Componnet {
  constructor(props) {
    super(props);
    this.state = {msg: 'hello',};

    // 为了在回调中使用 `this`,这个绑定是必不可少的
    this.msgHandle = this.msgHandle.bind(this);
  }
  msgHandle() {
    // 当前this如果不经过绑定,是 undefined
    this.setState(state => ({
      msg: `${state.msg}, Jack`
    }))
  }
  render() {
    return (
      <div>
        <div>{ this.state.msg }</div>
        <button onClick={this.msgHandle}>
          打招呼
        </button>
      </div>
    )
  }
}

this的指向性问题

上面代码写法没法用 state简化,且必须绑定 this
箭头函数
箭头函数本身没有this,谁调用的箭头函数,则函数内的this指向谁

  • 方式一:利用这个特性,我们在方法调用时可以使用箭头函数
class Hello extends React.Componnet {
  state = {
    msg: 'hello',
  }
  msgHandle() {
    this.setState(state => ({
      msg: `${state.msg}, Jack`
    }))
  }
  render() {
    return (
      <div>
        <div>{ this.state.msg }</div>
        // 箭头函数调用
        <button onClick={() => this.msgHandle()}>
          打招呼
        </button>
      </div>
    )
  }
}
  • 方式二:函数使用箭头函数形式定义

该语法为实验性语法,但由于babel的存在可以直接使用

class Hello extends React.Componnet {
  state = {
    msg: 'hello',
  }
  // 箭头函数定义
  msgHandle = () => {
    this.setState(state => ({
      msg: `${state.msg}, Jack`
    }))
  }
  render() {
    return (
      <div>
        <div>{ this.state.msg }</div>
        <button onClick={this.msgHandle}>
          打招呼
        </button>
      </div>
    )
  }
}

六、表单数据绑定

受控组件

class Hello extends React.Componnet {
  state = {
    msg: 'hello',
  }
  // 箭头函数定义
  msgHandle = (e) => {
    const {value, name} = e.target
    this.setState(state => ({
      // 引用变量
      [name]: value
    }))
  }
  render() {
    return (
      <div>
        <input type="text" name="msg" value={this.state.msg} onChange={this.msgHandle} />
      </div>
    )
  }
}

ref

class Hello extends React.Componnet {
  constructor() {
    super();
    // 创建ref
    this.msgRef = React.createRef()
  }
  msgHandle = () => {
    console.log('文本框内容为:', this.msgRef.current.value)
  }
  render() {
    return (
      <div>
        <input type="text" ref={ this.msgRef } />
        <button onClick={ this.msgHandle }>
          获取文本框的值
        </button>
      </div>
    )
  }
}

七、JSX语法

1、条件渲染

{
  a ? (<div></div>) : (<input />)
}

2、列表渲染

map()

<ul>
  {
    this.state.arr.map((item, index) => {
      <li :key={index}>
        {item.value}
      </li>
    })
  }
</ul>

八、props

1、特性

  • 可传任何类型的数据
  • 只读
  • 在类组件中,如果有constructor, 则props需要传递给super(),否则在构造函数内无法使用props
// 字符串
name="hello"
// 数值
age={19}
// 数组
colors={[blue, black, white]}
// 函数
fn={() => console.log('hello')}
// JSX
hm={<h1>Hello</h1>}

constructor(props){
  super(props);
}

2、获取props

函数组件通过参数props接受数据
类组件通过this.props接受数据

3、children

当使用组件时,当组件内部有内容时,组件中可通过props.children读取到该内容(类似Vue的slot)

// 使用Child组件
<Child>我是一个组件</Child>

// Child组件内部
this.props.children === '我是一个组件'  // true

3、类型约束

// 下载包  
npm install prop-types
// 使用
import PropTypes from 'prop-types'

function App(props) {}

// 指定props类型
App.propTypes = {
  // 常见类型:array, bool, func, number, object, string
  props名: props类型(PropTypes.array)
  // 设置为必填:isRequired
  props名: PropTypes.array.isRequired
}

九、组件间的数据传递

父 --> 子

传递数据props

子 --> 父

传递方法props

兄弟组件

  • 方案一:将数据存放到两个组件的父组件
  • 方案二:消息订阅-发布机制
    • 安装工具库PubSubJS:npm i pubsub-js -S
    • 引入:import PubSub from 'pubsub-js'
    • 发布:PubSub.publish('标识'), data)
    • 接收:PubSub.subscribe('标识', function(data){}
    • 卸载:PubSub.unsubscribe()

祖孙甚至更深层嵌套关系的组件

Context

// 通过React.createContext创建两个组件:Provider(数据提供),Consumer(数据使用)
const {Provider, Consumer} = React.createContext()

// 使用Provider作为父组件,并通过value作为props进行传递
<Provider value="propsData">
  <Child />
</Provider>

// 在需要使用数据的组件中通过Consumer使用数据
// Child组件
<div>
  <Consumer>
    {
      data => <span>{ data }<span>
    }
  </Consumer>
</div>
Last Updated 2023-04-02 15:01:41