react基础1

官网:https://react.docschina.org

一、认知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

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

react基础1
<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>
react基础1

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、参数用{}单括号
react基础1
        const num = 1
        const vnodes = (
            <div>
                <h3>{num}</h3>
                <div>{num > 10 ? 'a' : 'b'}</div>
            </div>
        )
react基础1

4)、动态绑定

1、动态属性:直接写{}
2、jsx      class改成className
3、jsx      for改成htmlFor
4、style    写{{fontSize:'14px',color:'red'}}
5、解析html  dangerouslySetInnerHTML={{__html:html}}
react基础1
        const title = '按钮'
        const html = '<a herf="">ff</a>'
        const vnode1 = (
            <div className='jj'>
                <button title={title}>{title}</button>
            </div>
        )
react基础1

5)、数组

react基础1
  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>

        )
react基础1

6)、插入

ReactDOM.render(vnode, app)

三、React脚手架

1、创建

  npx create-react-app  项目名称

react基础1

 

  这些文件没啥用删掉他们

 react基础1

 

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

react基础1

2、组件

1)、函数组件

react基础1
import React ,{Component}from 'react'
function App(){
    return(
        <div>普通</div>
    )
}
const App=()=>{
    return(
        <div>
            es6
        </div>
    )
}
export default App
react基础1

2)、类组件

react基础1
import React ,{Component}from 'react'
class App extends Component{
    render(){
        return(
            <div>类写法</div>
        )
    }
}
export default App
react基础1

3、事件处理

react基础1
该表事件绑定指向
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) } }
react基础1

4、state状态

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

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

修改

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

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

 

三、组件传值

1、props相关

props与state区别

  • props 中存储的数据,都是外界传递到组件中的
  • props 中的数据,都是只读的
  • state 中的数据,都是可读可写的
  • props 在函数声明或类申明的组件中都有
  • state 只有类申明的组件中才有

1)、父子组件传值props

  父组件 

 <Home name={'zhangzhang1'}></Home>

  函数组件

react基础1
const App=(props)=>{
    return(
        <div>
            {props.name}
        </div>
    )
}
react基础1

  类组件

react基础1
class App extends Component{
    render(){
        return(
            <div>
                <h3>
                    {this.props.name}
                </h3>
            </div>
        )
    }
}
 
react基础1

2)、props之children属性

父组件

 <Home >我是children中的值</Home>

接收

react基础1
class App extends Component{
    render(){
        return(
            <div>
                <h3>
                    {this.props.children}
                </h3>
            </div>
        )
    }
}
 
react基础1

3)、props-type限制传入类型

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

下载:npm i -S prop-types

参数

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

- React元素类型:  element

- 必填项:     isRequired

- 特定结构的对象: shape({})

函数组件

react基础1
import PrTypes from 'prop-types'
const Cmp = (props) => {

    Cmp.defaultProps = { //默认值

        name: '标题'

    }

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

类组件

react基础1
import PrTypes from 'prop-types'
class Cmp extends Component {
    // 静态方法不能适用this
    static propTypes = {
        name: ProTypes.string
    }
    render() {
        return (
            <div>{this.props.name}</div>
        )
    }
}
react基础1

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方式获取表单元素值

react基础1
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)
  }
}
react基础1

6)、无修改不渲染

  shouldComponentUpdate

react基础1
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> ) } }
react基础1

  PureComponent

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

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

 

2、其他组件通信

1)、父组件--子组件

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

  子组件

react基础1
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'
        })
    }
}
react基础1

  父组件

react基础1
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()
    }
}
react基础1

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    //订阅
}

  二、祖先

react基础1
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>
        )
    }
}
react基础1

    三、接收的后代

react基础1
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>
        )
    }
}
react基础1

  兄弟节点之前通信

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

    祖先

react基础1


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>
    )
  }
react基础1

    兄弟1

react基础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()
  }
}
react基础1

    兄弟2

  <Consumer>
        {
          value => <h3>{value.count}</h3>
        }
      </Consumer>
    )
上一篇:react项目使用路由调整nginx 404的问题


下一篇:React中的ajax请求和跨域问题