本文目录

  • 1、react中使用antd组件库
  • 2、Immutable
  • 2.1 深拷贝和浅拷贝的关系
  • 2.2 immutable优化性能方式
  • 2.3 immutable的Map使用
  • 2.4 immutable的List使用
  • 2.5 实际场景formJS
  • 3、redux中使用immutable
  • 4、react路由中使用ts
  • 5、redux中使用ts
  • 6 、styled-components
  • 6.1 安装使用
  • 6.2 基于props做样式判断
  • 6.3 样式化任意组件
  • 6.4 动画


1、react中使用antd组件库

运行命令create-react-app antd-react创建新项目:

react antd TreeSelect 设置默认值_javascript


运行命令npm i antd安装:

react antd TreeSelect 设置默认值_react.js_02


使用:

import React from 'react'
import ReactDOM from 'react-dom'
import 'antd/dist/antd.css';
import { Button } from 'antd';

ReactDOM.render(
    <div>
        <Button type="primary">Primary Button</Button>
    </div>, 
    document.getElementById("root"));

react antd TreeSelect 设置默认值_ci_03

2、Immutable

每次修改一个immutable对象时都会创建一个新的不可变的对象,在新对象上操作并不会影响到原对象的数据。

2.1 深拷贝和浅拷贝的关系

1、Object.assign或者... 只是一级属性赋值,比浅拷贝多拷贝了一层而已。
2、const obj1 = JSON.parse(JSON.stringify(obj)) 数组,对象都好用(缺点:不能有字段为undefined)。

2.2 immutable优化性能方式

immutable实现的原料是Persistent Data Structure(持久化数据结构),也就是使用旧数据创建新数据时,要保准旧数据同时可用且不变。同时为了避免deepCopy把所有节点都复制一遍带来的性能损耗,immutable使用了structural sharing(结构共享),即如果对象树中一个节点发生变化,只修改这个节点和受它影响的父节点,其它节点则进行共享。

安装输入命令npm i immutable

react antd TreeSelect 设置默认值_ci_04

2.3 immutable的Map使用

map使用(map只能套一层,如果属性还是对象或者数组的话就再套一层):

import React from 'react'
import { createRoot } from 'react-dom/client';
import 'antd/dist/antd.css'
import { Button } from 'antd'
import {Map} from 'immutable'

var obj = {
    name: 'immutable'
}

var oldObj = Map(obj)
console.log(oldObj)

// 更改值
var newObj = oldObj.set('name', 'react')

// 1.获取值:get获取
console.log(oldObj.get('name'), newObj.get('name'))

// 2.获取值:普通对象
console.log(oldObj.toJS(), newObj.toJS())

const container = document.getElementById('root')
const root = createRoot(container)
root.render(
    <div>
        <Button type="primary">Primary Button</Button>
    </div>
)

效果:

react antd TreeSelect 设置默认值_javascript_05


state中使用:

import React, { Component } from 'react'
import { Map } from 'immutable'

export default class imMap extends Component {

  state = {
    info: Map({
      name: 'immutable',
      key: 100
    })
  }

  render() {
    return (
      <div>
        <button onClick={() => {
          this.setState({
            info: this.state.info.set('name', 'react').set('key', 101)
          })
        }}>onclick</button>
        {this.state.info.get('name')} -- 
        {this.state.info.get('key')}
      </div>
    )
  }
}

可以看到多个值时,immutable可以链式操作。

2.4 immutable的List使用

import React, { Component } from 'react'
import {List} from 'immutable'

var arr = List([1,2,3])
var arr1 = arr.push(4)
var arr2 = arr1.concat([5])

console.log(arr.toJS(), arr1.toJS(), arr2.toJS())

export default class ImList extends Component {
  render() {
    return (
      <div>ImList</div>
    )
  }
}

效果:

react antd TreeSelect 设置默认值_ci_06


2.5 实际场景formJS

在实际开发中我们的state中数据结构一般来自后端返回的,那么我们将使用formJS

import React, { Component } from 'react'
import { fromJS } from 'immutable'

export default class ImFromJs extends Component {
    state = {
        info: fromJS({
            list: ['1', '2', '3'],
            obj: {
                name: 'immutable',
                key: 100,
            }
        })
    }

    render() {
        return (
            <div>ImFromJs
                <div><button onClick={() => {
                    this.setState({
                        info: this.state.info.setIn(['obj', 'name'], 'react')
                    })
                }}>改变标题</button></div>
                <div><button onClick={() => {
              this.setState({
                  info: this.state.info.updateIn(['list'], (oldList) => {
                    return oldList.push(oldList._tail.array.length + 1)
                  })    
              })
          }}>改变数组</button></div>
                <div>{this.state.info.getIn(['obj', 'name'])}</div>
                <div>
                    <ul>
                        {
                            this.state.info.get('list').map((item, index) => {
                                return <li key={index}>{item} 
                                <button onClick={() => {
                                    this.setState({
                                        info: this.state.info.updateIn(['list'], (oldList) => {
                                            return oldList.splice(index, 1)
                                        })
                                    })
                                }}>del</button>
                                </li>
                            })
                        }
                    </ul>
                </div>
            </div>
        )
    }
}

效果:

react antd TreeSelect 设置默认值_javascript_07

3、redux中使用immutable

react antd TreeSelect 设置默认值_前端_08


react antd TreeSelect 设置默认值_react.js_09


4、react路由中使用ts

输入命令npm i react-router-dom@5安装路由:

react antd TreeSelect 设置默认值_react.js_10


再输入命令:npm i --save-dev @types/react-router-dom安装路由类型推断。新建如下文件:

react antd TreeSelect 设置默认值_react.js_11


Film.tsx写入如下代码:

import axios from 'axios'
import { Component } from 'react'
import { RouteComponentProps } from 'react-router-dom'

interface JItem {
    cinemaId: number,
    name: string
}

export default class Film extends Component<RouteComponentProps> {

  state = {
    cinemaList: []
  }  

  componentDidMount() { 
    axios({
        url: 'https://m.maizuo.com/gateway?cityId=110100&ticketFlag=1&k=3085018',
        method: 'get',
        headers: {
            'X-Client-Info':' {"a":"3000","ch":"1002","v":"5.2.0","e":"1646314068530784943341569"}',
            'X-Host': 'mall.film-ticket.cinema.list'
        }
    }).then((res) => {
        this.setState({
            cinemaList: res.data.data.cinemas
        })
    }).catch((err) => {
        console.log(err)
    })
   }
    
  render() {
    return (
      <div>
          <ul>
          {
              this.state.cinemaList.map((item: JItem) => 
                <li key={item.cinemaId} onClick={() => {
                    this.props.history.push(`/cinema/${item.cinemaId}`)
                }}>{item.name}</li>
              )
          }
          </ul>
      </div>
    )
  }
}

Cinema.tsx写入如下代码:

import { Component } from 'react'
import { RouteChildrenProps } from 'react-router-dom'

interface IParams {
    cinemaId: string
}

export default class Cinema extends Component<RouteChildrenProps<IParams>> {

  componentDidMount() { 
      console.log((this.props.match?.params as any).cinemaId)

      console.log(this.props.match?.params.cinemaId)
   }  

  render() {
    return (
      <div>Cinema</div>
    )
  }
}

新建router\router.tsx,写入代码:

import { Component } from 'react'
import {HashRouter, Route} from 'react-router-dom'
import Center from '../component/Center'
import Cinema from '../component/Cinema'
import Film from '../component/Film'

export default class Router extends Component {
  render() {
    return (
      <HashRouter>
          <Route path="/film" component={Film}></Route>
          <Route path="/cinema/:cinemaId" component={Cinema}></Route>
          <Route path="/center" component={Center}></Route>
      </HashRouter>
    )
  }
}

新建router\index.tsx,写入代码:

import React, { Component } from 'react'
import store from '../redux/store'
import Router from './router'

export default class Index extends Component {

  render() {
    return (
      <div>
          <Router></Router>
      </div>
    )
  }
}

可以看到ts的写法与普通js写法多了RouteComponentProps类型推断,并且自己写的interface JItem接口去对接cinemaIdname类型。
Cinema.tsx子组件中,也多了RouteComponentProps类型推断,并且取路由传参过来的值,第一种方法使用了类型推断。第二种方法是自己写了一个接口去对接类型。这两种方法都可以取到值。

效果:

react antd TreeSelect 设置默认值_前端_12


react antd TreeSelect 设置默认值_ci_13


5、redux中使用ts

新建redux\store.ts,写入如下代码:

import { createStore } from "redux"


interface IAction {
    type: string,
    payload?: any
}
interface IState {
    isShow: boolean
}

const reducer = (prevState:IState={
    isShow: true
},
    action: IAction) => {
        const {type} = action
        const newState = {...prevState}
        switch(type) {
            case "show":
                newState.isShow = true
                return newState
            case "hide":
                newState.isShow = false
                return newState
            default:
                return prevState
        }
    }

const store = createStore(reducer)

export default store

router\index.tsx修改为如下代码:

import React, { Component } from 'react'
import store from '../redux/store'
import Router from './router'

export default class Index extends Component {

  state = {
      isShow: store.getState().isShow
  }  

  componentDidMount() { 
      store.subscribe(() => {
          console.log(store.getState())
          this.setState({
            isShow: store.getState().isShow
          })
      })
   }

  render() {
    return (
      <div>
          <Router></Router>
          {
              this.state.isShow && <div>显示/隐藏</div>
          }
      </div>
    )
  }
}

可以看到在redux中我们定义了两个接口去限制了stateaction的类型推断,让我们在写代码的阶段就能够将写错字母的问题给提前发现。效果:

react antd TreeSelect 设置默认值_css_14


react antd TreeSelect 设置默认值_react.js_15


6 、styled-components

6.1 安装使用

styled-components它是通过javascript改变css编写方式的解决方案之一,从根本上解决常规css编写的一些弊端。
通过javascript来为css赋能,能达到常规css所不好处理的逻辑复杂、函数方法、复用、避免干扰。样式书写将直接依附在jsx上面,htmlcssjs三者再次内聚。all is js思想。

运行安装命令npm i styled-components

react antd TreeSelect 设置默认值_css_16


在项目中创建文件夹styled-components及其子文件StyleComponent.js,并在index.js引入:

react antd TreeSelect 设置默认值_react.js_17


StyleComponent.js写入代码:

import React, { Component } from 'react'
import styled from 'styled-components'

export default class StyleComponent extends Component {
  render() {

    const StyledFooter = styled.footer`
        background:yellow;
        position: fixed;
        left: 0;
        bottom: 0;
        width: 100%;
        height: 50px;
        line-height: 50px;
        text-align: center;
        ul {
            display: flex;
            list-style-type: none;
            li {
                flex: 1;
            }
        }
    `

    return (
      <StyledFooter>
          <ul>
              <li>首页</li>
              <li>列表</li>
              <li>我的</li>
          </ul>
      </StyledFooter>
    )
  }
}

效果:

react antd TreeSelect 设置默认值_javascript_18


可以看到我们引入的styled就是一个组件.footer将会生成footer标签并用模版字符串进行样式写法,支持像sass的嵌套写法


6.2 基于props做样式判断

import React, { Component } from 'react'
import styled from 'styled-components'

export default class StyleComponent extends Component {
  render() {

    const StyledButton = styled.button`
    background: ${props=>props.bg || 'blue'}
    
    `

    return (
      <div>
        <StyledButton>btn</StyledButton>
        <StyledButton bg="yellow">btn</StyledButton>
      </div>
    )
  }
}

react antd TreeSelect 设置默认值_前端_19


效果:

react antd TreeSelect 设置默认值_javascript_20


6.3 样式化任意组件

import React, { Component } from 'react'
import styled from 'styled-components'

export default class StyleComponent extends Component {
  render() {

    const Child = (props) => <div className={props.className}>child</div>

    const StyledChild = styled(Child)`
    background: ${props=>props.bg || 'blue'};
    color: #fff;
    `

    return (
      <div>
        <StyledChild>btn</StyledChild>
      </div>
    )
  }
}

react antd TreeSelect 设置默认值_javascript_21


6.4 动画

import React, { Component } from 'react'
import styled, {keyframes} from 'styled-components'

export default class StyleComponent extends Component {
  render() {

    const rotate360 = keyframes`
        from {
            transform: rotate(0deg);
        }
        to {
            transform: rotate(360deg);
        }
    `
    const Rotate = styled.div`
    position: absolute;
    left: 50px;
    top: 100px;
    background: blue;
    width: 100px;
    height: 100px;
    animation: ${rotate360} 1s linear infinite;
    `

    return (
      <div>
        <Rotate></Rotate>
      </div>
    )
  }
}

效果:

react antd TreeSelect 设置默认值_ci_22


可以看到我们引入了keyframes,进行了动画编写。