react基础1

一、认知React

概述

React 起源于 Facebook(脸书) 的内部项目,它是一个用于构建用户界面的 javascript 库,Facebook用它来架设公司的Instagram网站,并于2013年5月开源。

React用于构建用户界面的 JavaScript 库,它不是一个完整的MVC框架

特点

  • 声明式
        你只需要描述UI看起来是什么样式,就跟写HTML一样,React负责渲染UI

  • 基于组件
        组件时React最重要的内容,组件表示页面中的部分内容

  • 应用场景
        使用React可以开发Web应用(ReactJs),使用React可以开发移动端(react-native),可以开发VR应用(react 360)

二、react写法基础

1、react应用

react有很多依赖库,其中有两个使我们必须引入的react.js、react-dom.js

下载地址

react.js 是核心,提供创建元素,组件等功能
https://unpkg.com/react@16/umd/react.development.js
react-dom.js 提供DOM相关功能
https://unpkg.com/react-dom@16/umd/react-dom.development.js

写法   必要的三个步骤(依赖的引入顺序不能乱)

<body>
    <div id="app"></div>
    <script src="./utils/react.development.js"></script>
    <script src="./utils/react-dom.development.js"></script>
    <script>
        //1、 获取插入节点
        const app=document.getElementById('app')
        // 2、创建虚拟dom
        const el=React.createElement
        const vnode=el(
            'div',
            null,
            el('h1',{id:1000},'hello w'),
        )
        // 3、把dom放到自定位置上
        ReactDOM.render(vnode,app)
    </script>
</body>

2、jsx介绍与用法

  • JSX 执行更快,因为它在编译为JavaScript代码后进行了优化
  • 它是类型安全的,在编译过程中就能发现错误
  • 声明式语法更加直观,与HTML结构相同,降低了学习成本,提升开发效率速
  • jsx语法中一定要有一个顶级元素包裹,否则编译报错,程序不能运行
引入依赖:
https://unpkg.com/babel-standalone@6/babel.min.js
1)、引入相关依赖
 <div id="app"></div>
    <script src="./utils//babel.min.js"></script>
    <script src="./utils/react.development.js"></script>
    <script src="./utils/react-dom.development.js"></script>
2)、创建dom元素
const app = document.getElementById('app')
        // 单行不需要(),多行需要
        const vnode = (<div>
            <dl>
                <dt>asd</dt></dl>
        </div>)
3)、表达式
 1、必须有最外成包裹
 2、注释放在{}内
 3、参数用{}单括号
const num = 1
        const vnodes = (
            <div>
                <h3>{num}</h3>
                <div>{num > 10 ? 'a' : 'b'}</div>
            </div>
        )
4)、动态绑定
1、动态属性:直接写{}
2、jsx      class改成className
3、jsx      for改成htmlFor
4、style    写{{fontSize:'14px',color:'red'}}
5、解析html  dangerouslySetInnerHTML={{__html:html}}

const title = '按钮'
        const html = '<a herf="">ff</a>'
        const vnode1 = (
            <div className='jj'>
                <button title={title}>{title}</button>
            </div>
        )
5)、数组
const users = ['11', '22', '33']
        const vnode2 = (
            <div>
                {
                    //    方案1
                }{
                    users.map((item, index) => {
                        return (<h3 key={index}>{item}</h3>)
                    })
                }
                {
                    // 方案2
                }
                {
                    users.map((item, index) => (
                        (<h3 key={index}>{item}</h3>)
                    ))
                }
            </div>

        )
6)、插入
ReactDOM.render(vnode, app)

三、React脚手架

1、创建

npx create-react-app 项目名称


image

这些文件没啥用删掉他们

image

修改文件--至此初始化完成

image

2、组件

1)、函数组件
import React ,{Component}from 'react'
function App(){
    return(
        <div>普通</div>
    )
}
const App=()=>{
    return(
        <div>
            es6
        </div>
    )
}
export default App
2)、类组件
import React ,{Component}from 'react'
class App extends Component{
    render(){
        return(
            <div>类写法</div>
        )
    }
}
export default App

3、事件处理

该表事件绑定指向export default class Solvethis extends Component {
    constructor(props) {
        super(props)
        // 方案1
        this.fun = this.fun.bind(this)
    }
    render() {
        return (
            <div>
                <button onClick={this.fun}>方案1</button>
                <button onClick={this.fun2.bind(this)}>方案2</button>
                <button onClick={() => this.fun()}>方案3</button>
                <button onClick={this.fun}>方案4</button>
            </div>
        )
    }
    fun() {
        console.log(this.props)
    }
    fun2() {
        console.log(this.props)
    }
    fun3() {
        console.log(this.props)
    }
    fun4 = () => {
        console.log(this.props)
    }
}

4、state状态

state状态只在class类组件才有,函数组件没有此功能。

export default class extends React.Component {
    constructor(props){
        super(props)
        // 第一种初始化方式
        this.state = {
            count : 0
        }
}
/*
    // 第二种初始化方式
    state = {
        count:1
}
*/
    render(){
        return (
            <div>计数器 :{this.state.count}</div>
        )
    }
}

修改

语法1
this.setState({
    key:value
})

语法2  官方推荐
this.setState(state => {
    key:value
})

三、组件传值

1、props相关

props与state区别
  • props 中存储的数据,都是外界传递到组件中的
  • props 中的数据,都是只读的
  • state 中的数据,都是可读可写的
  • props 在函数声明或类申明的组件中都有
  • state 只有类申明的组件中才有
1)、父子组件传值props
父组件
<Home name={'zhangzhang1'}></Home>
函数组件
const App=(props)=>{
    return(
        <div>
            {props.name}
        </div>
    )
}
类组件
class App extends Component{
    render(){
        return(
            <div>
                <h3>
                    {this.props.name}
                </h3>
            </div>
        )
    }
}
2)、props之children属性
父组件
 <Home >我是children中的值</Home>
接收
class App extends Component{
    render(){
        return(
            <div>
                <h3>
                    {this.props.children}
                </h3>
            </div>
        )
    }
}
3)、props-type限制传入类型

组件调用者可能不知道组件封装着需要什么样的数据,如果传入的数据不对,可能会导致程序异常,所以必须要对于props传入的数据类型进行校验。

下载:npm i -S prop-types

参数
    - 类型:        array、bool、func、number、object、string

    - React元素类型:  element

    - 必填项:     isRequired

    - 特定结构的对象: shape({})
函数组件
import PrTypes from 'prop-types'
const Cmp = (props) => {
    Cmp.defaultProps = { //默认值
        name: '标题'
    }

   Cmp.propTypes = {
        name: PrTypes.number
    }
    return(
    <div>{props.name}</div>
    )

}
类组件
import PrTypes from 'prop-types'
class Cmp extends Component {
    // 静态方法不能适用this
    static propTypes = {
        name: ProTypes.string
    }
    render() {
        return (
            <div>{this.props.name}</div>
        )
    }
}
4)、受控组件

将state与表单项中的value值绑定在一起,有state的值来控制表单元素的值,称为受控组件。

<input type="text" value={this.state.username} onChange={this.inputChange.bind(this)} />
//注:多表单元素需优化事件方法
this.setState({
   [e.target.name]: e.target.value
})
5)、非受控组件

没有和state数据源进行关联的表单项,而是借助ref,使用元素DOM方式获取表单元素值

class App extends React.Component {
  constructor(props){
    super(props)
    //创建 ref
    this.username = React.createRef()
  }
  render(){
    return (
        <div>
          <input type ="text" ref={this.username} />
          <button onClick ={this.fn}>获取值</button>
        </div>
    )
  }
  // 获取文本框的值
  fn =() => {
    console.log(this.username.current.value)
  }
}
6)、无修改不渲染

shouldComponentUpdate

import React, { Component, PureComponent } from 'react'
export default class SApp extends Component {
    shouldComponentUpdate(nextProps, nextState) {
        /* 
           旧得props
                这时的props还没更新
                state同理
                PureComponent 与Component 功能相似的,区别在于React.PureComponent 内部自动实现了             shouldComponentUpdate钩子,不需要手动进行比较操作。

         */
        if (nextProps.name == this.props.name) {
            return false
        }
        return true

    }
    render() {
        return (
            <div>{this.props.name}</div>
        )
    }
}

PureComponent

React.PureComponent 与 React.Component 功能相似的,区别在于React.PureComponent 内部自动实现了 shouldComponentUpdate钩子,不需要手动进行比较操作。

import React, { Component, PureComponent } from 'react'
export default class SApp extends PureComponent { 
   render() { 
    return ( 
      <div>{this.props.name}</div>  
      ) 
  } 
}

2、其他组件通信

1)、父组件--子组件

原理:通过ref非受控组件 ,利用createRef进行子元素方法来改变内容

子组件

import React,{Component} from 'react'
export default class Child extends Component{
    state={
        title:'sad'
    }
    render(){
        return(
            <div>
                {this.state.title}
            </div>
        )
    }
    setTitle(){
        this.setState((state)=>{
            title:'999'
        })
    }
}

父组件

import React,{Component,createRef} from 'react'
import SonView from './components/SonListen'
export default class Father extends Component{
    constructor(props){
        super(props)
        this.son=createRef()
    }
    render(){
        return(
            <div>
                <SonView ref={this.son}></SonView>
                <button onClick={this.func.bind(this)}></button>
            </div>
        )
    }
    func(){
        const sonValue=this.son.current
        sonValue.setTitle()
    }
}

2)、子组件---父组件

父组件将自己的某个方法传递给子组件,在方法里可以做任意操作,比如可以更改状态,子组件通过this.props接收到父组件的方法后调用。

 <SonView sonClick={this.son}></SonView> 父组件

<button onClick={this.props.sonClick(id)}></button> 子组件
3)、跨组件通信
祖先--子孙

一、定义数据源

import React ,{creatContext} from 'react'
let {Provider,Consumer}=creatContext()
export{
    Provider, //发布
    Consumer    //订阅
}

二、祖先

import React,{Component} from'react'
import {Provider,Consumer} from './store'
import Son1 from './Son1'
export default class App extends Component{
    constructor(props){
        super(props)
        this.state={
            name:'uuu'
        }
    }
    render(){
        return(
            <div>
                <Provider value={this.state.name}>
                    <Son1></Son1>
                </Provider>
            </div>
        )
    }
}

三、接收的后代

import React,{Component} from'react'
import {Consumer} from './store'
export default class Son1 extends Component{
    constructor(props){
        super(props)
        this.state={
            name:'uuu'
        }
    }
    render(){
        return(
            <div>
                <Consumer>
                   {
                        value=>{
                            <div>{value.name}</div>
                        }
                   }
                </Consumer>
            </div>
        )
    }
}
兄弟节点之前通信

原理:一个子物体挂在事件,另一个挂在属性,通过实践改变属性,来改变另一个组件接受的内容
祖先

state = {
    count: 1,
    setCount: () => {
      this.setState(state => {
        return {
          count: ++state.count
        }
      })
    }
  }
render() {
    let { count, setCount } = this.state
    return (
      <div>
        <Provider value={{ count, setCount }}>
          {/* 兄弟 */}
          <Cmp1></Cmp1>
          <Cmp2></Cmp2>
        </Provider>
      </div>
    )
  }

兄弟1

import React, { Component ,createContext} from 'react'

export default class Cmp2 extends Component {
  // 只得到了默认数据 --> 没有包裹在Provider组件中
  static contextType = createContext

  render() {
    return (
      <div>
        <button onClick={this.setCount.bind(this)}>自增数据</button>
      </div>
    )
  }
  setCount() {
    this.context.setCount()
  }
}

兄弟2

<Consumer>
        {
          value => <h3>{value.count}</h3>
        }
      </Consumer>
    )
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容