react hook+动画+组件库ant

1- hook

1- 什么是hooks?

Hook 是 React 16.8 的新增特性。它可以让你在不编写 class 的情况下使用 state 以及其他 的 React 特性。

2- 主要解决的问题

1.用于在函数组件中引入状态管理和生命周期方法;

2.取代高阶组件和render props来实现抽象和可重用性;

3.完全脱离"类",便可写出一个全功能的组件。

3- 常用的钩子:

3-1 useState

作用: 使函数组件也可以拥有状态,后期状态更新时可以引起视图更新

import React,{useState} from 'react'
​
export default function UseState() {
    // let name='小黑'
​
    // 第一个接收状态,  第二个接收 修改当前状态的方法 
    let [name,setName] = useState('小黑')
    // 可以多次调用
    let [age,setAge] = useState(18)
    let[sex,setSex]  =useState('男')
​
    let [state,setState] = useState({
        name:'小黑',
        age:18,
        sex:'男'
    })
​
    function changeName(){
        // name='小白'
        setName('小白')
        console.log(name);
    }
    function changeObj(){
        setState({
            ...obj,
            age:99
        })
    }
    return (
        <div className='box'>
            <h1>useState组件</h1>
            <button onClick={()=>changeName()}>修改name</button>
            <button onClick={()=>setName('小白')}>修改name</button>
            <h2>{name}</h2>
            <button onClick={()=>changeObj()}>修改age</button>
            <h2>{state.age}</h2>
            <h2>{state.sex}</h2>
        </div>
    )
}
​

3-2 useEffect

作用: 使函数组件有类似componentDidmount,componentDidUpdate,componentWillUnmount的功能

 // 方式一:  componentDidMount  + componentDidUpdate
    // useEffect(()=>{
    //     console.log('useEffect触发');
    // })
​
    // 方式二:componentDidMount
​
    // useEffect(()=>{
    //     console.log('useEffect触发');
    // },[])
​
    // 方式三:  componentDidMount, name状态更新是会触发
    // useEffect(()=>{
    //     console.log('useEffect触发');
    // },[name])
​
    // 方式四: componentDidMount + componentDidUpdate + componentWillUnmount
    // return的函数时销毁之前触发
    useEffect(()=>{
       let timer = setInterval(()=>{
            setTime(new Date())
        },1000)
​
        return ()=>{
            // 销毁之前清除定时器
            clearInterval(timer)
        }
    })

3-3 useReducer

作用: 使函数组件有状态管理

// 状态管理
​
export let initState = {
    age:19,
    name:'小红'
}
​
const TYPES={
    CHANGENAME:'CHANGENAME',
    CHANGEAGE:'CHANGEAGE'
}
​
export function reducer(state=initState,action){
    switch(action.type){
        case TYPES.CHANGENAME:
            return {
                ...state,
                name:action.name
            }
        case TYPES.CHANGEAGE:
            return {
                ...state,
                age:action.age
            }
        default:
            return {
                ...state
            }
    }
}
​
export const actions = {
    changeName:(name)=>({type:TYPES.CHANGENAME,name}),
    changeAge:(age)=>({type:TYPES.CHANGEAGE,age:age})
}
​

---组件

import React,{useReducer} from 'react'
​
import {initState,reducer,actions} from './red'
​
export default function UserReducer() {
    // 创建状态管理
    let [state,dispatch] = useReducer(reducer,initState)
​
    function change(){
        // 修改name
        // dispatch({type:'changeName',name:'小会'})
        // 触发action,修改状态, 可以视图更新
        dispatch(actions.changeName('小灰灰'))
    }
    return (
        <div className='box'>
            <h1>UserReducer组件</h1>
            <button onClick={()=>change()}>修改name</button>
            <h1>{state.name}---{state.age}</h1>
        </div>
    )
}
​

3-4 useContext

作用: 多个组件之间状态传递

​
import React,{useReducer,createContext,useState} from 'react'
​
import {initState,reducer,actions} from './red'
import Child from './Child'
​
​
export let myContext = createContext()
​
export default function UserReducer() {
    // 创建状态管理
    let [state,dispatch] = useReducer(reducer,initState)
​
    let [name,setName] = useState('小黑')
    function change(){
        // 修改name
        // dispatch({type:'changeName',name:'小会'})
        // 触发action,修改状态, 可以视图更新
        dispatch(actions.changeName('小灰灰'))
    }
    return (
        <div className='box'>
            <h1>UserReducer组件</h1>
            <button onClick={()=>change()}>修改name</button>
            <h1>{state.name}---{state.age}</h1>
            <myContext.Provider value={state}>
                 <Child></Child>
            </myContext.Provider>
           
        </div>
    )
}
​

---后代组件接收

import React,{useContext} from 'react'
import {myContext} from './UserReducer'
​
export default function ChildChild() {
​
    // 接收provider发送的数据
    let state = useContext(myContext)
    return (
        <div className='box'>
            <h1>ChildChild组件</h1>
            <h1>{state.name}---{state.age}</h1>
        </div>
    )
}
​

4- hook注意

  • 只在函数组件顶层使用,不可以在循环和条件或者嵌套函数中使用

  • 只在react函数中调用。 不要用在普通的js函数中

2- 动画

1. 安装

npm i react-transition-group --save

2- 使用

  • unmountOnexit 结束时销毁, 必填属性

  • in 设置动画关联的状态 必填属性

  • timeout 动画时长 必填属性

  • classNames=‘f’ 设置动画的类名 必填属性

    • f-enter: 显示时,动画开始的状态

    • f-enter-active 显示时,动画的过程

    • f-exit: 消失时,动画的开始状态

    • f-exit-active 消失时,动画的过程

  • onEnter: 显示时,动画开始执行的回调函数

  • onEntering: 显示时,动画执行中的回调函数

  • onEntered; 显示时,动画执行结束的回调函数

  • onExit: 消失时,动画开始执行的回调函数

  • onExiting: 消失时,动画执行中的回调函数

  • onExited: 消失时,动画执行结束的回调函数

1- 单元素动画

 <CSSTransition  
     onExited={()=>{console.log('动画结束了');}} 
     onExit={()=>{console.log('动画要开始了');}} 
     classNames='f' 
     unmountOnExit 
     timeout={3000} 
     in={this.state.flg}>
                    <h1>React的动画</h1>
                </CSSTransition>
                

2- 列表动画

 <h1>列表动画</h1>
​
<TransitionGroup>
    {this.state.arr.map((item,i)=>{
         return (
          <CSSTransition key={item} classNames='f' timeout={1000} unmountOnExit>
                  <li>{item}   <button onClick={()=>this.del(i)}>移出</button></li>
          </CSSTransition>
      )
    })}
  </TransitionGroup>

3- 组件库ant

1- 安装

npm i antd --save

2- 使用

1- 全部导入

---index.js

import 'antd/dist/antd.css'

2- 按需加载

2-1 手动按需加载

// 按需加载
import 'antd/es/button/style/index.css'
import 'antd/es/breadcrumb/style/index.css'

2-2 借助插件自动按需加载

  • 安装插件

npm i babel-plugin-import --save
  • 修改.babelrc文件的插件配置

{
    "presets": [
    "react-app"
    ],
    "plugins": [
        ["import", { "libraryName": "antd", "style": "css" }] 
    ] 
 }
  • 修改config/webpack.config.js

    • 需要npm run eject 导出配置文件

      npm run eject
      ​
      git add .
      git commit -m 注释
      ​
      npm run eject 
    • 在package.config.js修改 443行

      babelrc: true,     //443
    • package.json 删除多余的代码

      babel:{
          "presets": [
          "react-app"
          ]
      }
  • 启动项目

antd-mobile

1- 安装

npm i antd-mobile --save

2- 使用

1- 修改html

<!DOCTYPE html>
<html>
<head>
  <!-- set `maximum-scale` for some compatibility issues -->
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
  <script src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js"></script>
  <script>
    if ('addEventListener' in document) {
      document.addEventListener('DOMContentLoaded', function() {
        FastClick.attach(document.body);
      }, false);
    }
    if(!window.Promise) {
      document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js"'+'>'+'<'+'/'+'script>');
    }
  </script>
</head>
<body></body>
</html>

2- 全部导入

import 'antd-mobile/dist/antd-mobile.css';

3- 按需导入

如上

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值