react学习

react

框架库

  • react-router 路由
  • pubsub 消息管理
  • redux 状态管理
  • ant-design UI库

要点

  • jsx 最后翻译过来就是React.createElement方法

    createElement(element,options,content)

    elment 元素名称

    options 属性对象

    content 属性里面的内容

    demo: createElement('h1',{id:'test'},'hello react')

  • 虚拟dom解析后是Object
  • jsx注意事项

    1. 变量用一个大括号括起来;
    2. 如果引用class样式,需要用className
    3. 定义的jsx不需要引号,如果有多层,用小括号括起来
    4. 内联样式style要用对象的形式,且属性要用驼峰命名
    5. 只允许一个根标签
    6. 标签必须闭合
    7. 自定义组件以大写字母开头

      const name='zhangsan'
      const Rdom=(
          

      {name}

      {name}

      )
  • react创建函数组件

    1. 函数名大写,且要有返回值
    2. 引用需要用标签,且标签要有闭合

      function Demo(){
          return 

      demo test

      } ReactDOM.render(,document.getElementById('test'))
  • react创建类组件

    1. 自定义组件类必须继承React.Component
    2. 类组件里面必须定义render方法,并且需要返回值
    3. 调用组件,渲染到页面,组件是命名是大写开头
    4. 调用组件会new一个组件,然后调用render方法,且类里面this指向的是组件创建的实力对象,也叫组件实力对象。
    class MyComponent extends React.Component{
           render(){
               return (
                   

    test

    ) } } ReactDOM.render(,document.getElementById('test'))
  • react事件以及state

    1.节点绑定事件需要用on+事件名,需要驼峰命名

    2.事件的回调函数需要用bind重新绑定,否则this会丢失,或者用箭头函数赋值给属性,绑定该属性

    3.state对象里面需要定义需要变化的状态(属性)

    4.更改state里面的状态,需要用this.setState方法

    5.自定义方法需要用箭头函数赋值给属性,或者用bind方法绑定this

     class ChangeWeather extends React.Component{
         constructor(){
             super()
             this.state={
                 flag:true
             }
             this.changeFlag=this.changeFlag.bind(this)
         }
         render(){
             const {flag}=this.state
             return (
                 

    今天天气很{flag?'好':'不好'}

    ) } changeFlag(){ this.setState({ flag:!this.state.flag }) } } ReactDOM.render(,document.getElementById('test'))
      //上面例子精简版
    class ChangeWeather extends React.Component {
            state = { flag: true }
            render() {
                const { flag } = this.state
                return (
                    

    今天天气很{flag ? '好' : '不好'}

    ) } changeFlag = () => { this.setState({ flag: !this.state.flag }) } } ReactDOM.render(, document.getElementById('test'))
  • react里面的props

    1.通过标签传递属性,可以通过扩展运算符进行传递

    2.组件里面通过props引用

    3.如果是变量需要用大括号的形式进行传递

     class ChangeWeather extends React.Component{
           render (){
               return (
                   
    {this.props.title} {this.props.age} {this.props.obj.test} {this.props.test}
    ) } } const obj={ test:123 } ReactDOM.render(, document.getElementById('test'))
  • props的属性限制以及默认值

    1.16.x版本之前是用React.propsType.xxxx进行限制,之后的版本是需要引入propstype.js,然后再类的propTypes属性上面进行定义

    2.限制属性的时候,直接定义到类上面进行限制

    3.如果是函数限制传的类型为func,而不是function

    4.如果没有传值,需要给默认值,需要再类的defaultProps属性上面进行定义默认值

    5.定义的这些规则需要咋渲染之前进行定义

    6.定义的属性规则也可以用静态属性进行定义static

     //直接定义到类上面
    class ChangeWeather extends React.Component{
           
           render (){
               return (
                   
    {this.props.title} {this.props.age} {this.props.obj.test} {this.props.test}
    ) } } //需要再渲染之前进行规则定义,在类的propTypes上面进行定义 ChangeWeather.propTypes = { title: PropTypes.string.isRequired, fun:PropTypes.func.isRequired//函数要用func这个类型 } //默认值需要再类的defaultProps属性上面进行定义 ChangeWeather.defaultProps={ title:"fdsaf", fun:function(){} } const obj={ test:123, } ReactDOM.render(, document.getElementById('test'))
      //用静态属性的方式
    class ChangeWeather extends React.Component {
            static propTypes = {
                title: PropTypes.string.isRequired,
                fun: PropTypes.func.isRequired
            }
            static defaultProps = {
                title: "fdsaf",
                fun: function () { }
    
            }
            render() {
                return (
                    
    {this.props.title} {this.props.age} {this.props.obj.test} {this.props.test}
    ) } } const obj = { test: 123, } ReactDOM.render(, document.getElementById('test'))
  • react里面的ref

    1.在节点里面通过ref属性进行绑定

    2.在逻辑里面通过refs接受

    3.接受的ref是一个真实节点

      class Test extends React.Component{
    
            render(){
                return (
                    
    ) } btnClick=() => { const {input1}=this.refs alert(input1.value) } } ReactDOM.render(,document.getElementById('test'))

    4.ref通过回调方式获取

     /* ref  回调函数的形式 */
       class Reftest extends React.Component{
           inputel=null
           btnClick=() => {
               alert(this.inputel.value)
           }
           render(){
               return (
                   
    {this.inputel=el}}/>
    ) } } ReactDOM.render(,document.getElementById('test'))
    1. ref如果用内联的方式进行获取,在数据更新的 时候会调用两次回调函数,第一次会给回调函数传null第二次会传当前的节点。解决办法为直接用绑定的回调函数。只会调用一次回调函数,不会调用多次。但是内联和绑定的方式不会有任何影响。开发中一般用内联的方式进行开发。
    2. ref的创建方式三,通过React.createRef的方式创建。该函数调用后会返回一个对象,keycurrent的对象,值为节点。有多少个ref就要调用几次前面的函数。官方推荐写法

       /* ref  React.createRef的方式 */
         class Test extends React.Component{
             //有多少个就要创建多少个
             refstest=React.createRef();
             btnclick=()=>{
                 console.log(this.refstest.current.value);
                 
             }
             render(){
                 return (
                     
      //这里了是需要绑定上面返回的属性
      ) } } ReactDOM.render(,document.getElementById('test'))
  • react的非受控组件
  1. 所有的表单组件现用现取的组件。取值需要用到ref

1632151830939

​ 3.store.js

import { createStore } from "redux";
import countRedux from './count_redux'
export default createStore(countRedux)

4.count_action.js

import {ADD,DESC } from './constent'
export const add = (data) => ({
    type: ADD,
    data
})
export const desc = (data) => ({
    type: DESC,
    data
})

5.count_redux.js

import { ADD,DESC} from './constent'
export default function (preState=0, action) {
    const { type,data}=action
    switch (type) {
        case ADD:
            return preState + data
        case DESC:
            return preState - data

        default:
           return preState
    }
 }

6.constent.js

export const ADD='add'
export const DESC='desc'

7.index.js

import React from "react";
import ReactDOM from "react-dom";
import App from "./App.js";
import store from './redux/store'
ReactDOM.render(, document.getElementById('root'))
store.subscribe(() => {
    ReactDOM.render(, document.getElementById('root'))
})
  • 异步action

    1.引入并安装redux-thunk

    2.利用中间件传入thunk

    3.action返回的是一个函数,该函数会带有dispatch函数参数

    代码如下:

    store.js

    import { createStore, applyMiddleware  } from "redux";
    import countRedux from './count_redux'
    import thunk from 'redux-thunk'
    export default createStore(countRedux, applyMiddleware(thunk))

    action.js

    export const  addAsync = (data, time) => {
        //返回一个带有dispatch的参数的函数
        return (dispatch) => {
            setTimeout(() => {
                dispatch(add(data))//调用同步action
            },time)
        }
    }
  • react-redux

    1.引入并安装

    yarn add react-redux

​ 2.创建容器组件,用于操作状态以及包裹ui组件(链接ui组件以及redux)

      // 引入要展示的UI组件
import countUi from '../../components/Count'
// 用于连接UI组件以及redux
import { connect } from 'react-redux'
// 引入action
import { add, desc, addAsync } from '../../redux/count_action'
// 将store里面的状态映射到props,可以用过UI组件进行操作(ui组件通过this.props.xxx获取)
function mapStateToProps(state) { 
    return {
        count: state
    }
}
// 将store里面的操作状态的方法映射到props,可以用过UI组件进行操作(ui组件通过this.props.xxx获取)
function mapDispatchToProps(dispatch) {
    return {
        add: (num) => {
            dispatch(add(num))
        },
        desc: (num) => {  
            dispatch(desc(num))
        },
        addasync: (num, time) => {
            dispatch(addAsync(num,time))
        }
    }
}
export default connect(mapStateToProps, mapDispatchToProps)(countUi)     
  1. 通过props传递给子组件store
  2. UI组件的优化写法

    // 引入要展示的UI组件
    import countUi from '../../components/Count'
    // 用于连接UI组件以及redux
    import { connect } from 'react-redux'
    // 引入action
    import { add, desc, addAsync } from '../../redux/count_action'
    // 将store里面的状态映射到props,可以用过UI组件进行操作(ui组件通过this.props.xxx获取)
    /* function mapStateToProps(state) { 
    return {
        count: state
    }
    } */
    // 将store里面的操作状态的方法映射到props,可以用过UI组件进行操作(ui组件通过this.props.xxx获取)
    /* function mapDispatchToProps(dispatch) {
    return {
        add: (num) => {
            dispatch(add(num))
        },
        desc: (num) => {
            dispatch(desc(num))
        },
        addasync: (num, time) => {
            dispatch(addAsync(num,time))
        }
    }
    } */
    // export default connect(mapStateToProps, mapDispatchToProps)(countUi)
    
    // 优化写法
    export default connect(
    state => ({ count: state }),
    //这里可以返回一个简单对象,内部可以自动分发action
    {
        add: add,
        desc: desc,
        addasync: addAsync
    }
    )(countUi)

    5.引入react-redux可以不用手动监听转态变化

    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App.js";
    // import store from './redux/store'
    ReactDOM.render(, document.getElementById('root'))
    // 引入react-redux后可以不用手动监听状态变化
    // // 监测redux转态改变,redux状态改变会重新渲染页面
    // store.subscribe(() => {
    //     ReactDOM.render(, document.getElementById('root'))
    // })
    

    6.利用react-reduxprovider传递store

    import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App.js";
    import store from './redux/store'
    import { Provider } from 'react-redux'
    ReactDOM.render(
    
        
    
    , document.getElementById('root'))
    
    
  • 多个reducer利用combineReducers函数合并

    import { createStore, applyMiddleware ,combineReducers } from "redux";
    import countRedux from './reducers/count_redux'
    import person from "./reducers/person";
    import thunk from 'redux-thunk'
    
    export default createStore(
      // 多个reducer用combineReducers合并
      combineReducers({
        count: countRedux,
        person: person,
      }),
      applyMiddleware(thunk)
    );
  • reducer必须是一个纯函数,即传入的什么参数,就返回改参数,且传入的参数不能被改写。如果传入的是对象或者是数组。返回的值也应该是一个对象或数组,不可以在原有的对象或数组中进行操作再返回

    import { ADD_PERSON } from "../constent";
    export default function (prestate=[],action) { 
        const { type, data } = action;
        switch (type) {
          case ADD_PERSON:
            return [data,...prestate]
          default:
           return []
        }
    
    }
  • redux配置的开发者工具

    1. 谷歌浏览器安装redux-devtools
    2. 在项目中安装redux-devtools-extension
    3. store.js中进行如下配置

      import { createStore, applyMiddleware  } from "redux";
      import thunk from 'redux-thunk'
      import { composeWithDevTools } from "redux-devtools-extension";
      import reducers from "./reducers";
      export default createStore(
        // 多个reducer用combineReducers合并
        reducers,
        composeWithDevTools(applyMiddleware(thunk))
      );
  • 打包后的文件如何在本地启动

    1.全局安装serve插件

    npm install -g serve

    进入打包的文件目录运行serve命令

你可能感兴趣的:(react学习)