react学习

一、react基础

  1. jsx
    大括号的作用
    在这里插入图片描述
{count}
{userLlist.map((item)=>{return <li key={item.id}>{item.name}</li>}) }
key是用于react内部渲染处理的
  1. 基础条件渲染
{flag && <p>{"显示"}</p>}
  1. 复杂条件渲染
function getItem(){
  if(type==1) return <p>有图模式<p/>
  else if(type==2) return <>无图</>
  }

2、useState使用
state是状态变量,数据变化视图变化

const [userList,setUserList]=useState([{id:1,name:"z"}])

3.map,filter函数使用

4.tab切换功能实现

const tab={{type:" ",text:" "}}
//将type设为class高亮

在这里插入图片描述

5.loadsh使用排序

import * as _ from 'lodash'
setCommentList(_.orderby(commentList,'star'//字段名,'desc'))
//不改变原数组

6.classnames优化类名控制
在这里插入图片描述
7.受控绑定表单

<input 
 value={value} 
 onChange={(e)=>{
   setValue(e.target.value); //显示输入
 }}
 type='text'
 />

8.ref获取DOM对象

const inputRef=useRef(null);
<input ref={inputRef}/>
//使用inputRef.current获取DOM对象

9.uuid和dayjs库的使用
在这里插入图片描述

10.props使用

用于父传子组件消息

function Son(prop){
	prop.name
	prop.children //特殊属性
}
function Father(prop){
	return <Son name="xxx"><p>this is span<p/></Son>
}

在这里插入图片描述
11.子传父,兄弟之间传消息(利用子传父,父传兄弟)

12.使用Context跨层通信

1、全局中createContext创建一个Context上下文对象
2、上层用<Context.Provider value={mdg}></>传递数据
3、底层用useContext(Context)方法获取数据

*13.UseEffect

在这里插入图片描述
在这里插入图片描述

    const [commentList,setCommentList]=useState([])
    useEffect(()=>{
        async function getCommentList(){
            // async异步,await等待
            const res=await fetch('/comment').then(res=>res.json().then(data=>{console.log(data);return data}))   
            setCommentList(res);
        }
        getCommentList()
    },[])

在这里插入图片描述
清除副作用,最常见是在组件卸载时候
在这里插入图片描述
14.自定义hook

  1. 构造一个use开头的函数名
  2. 在函数体内封装可复用的逻辑
  3. 把组件中用到的状态变量return出去
    在这里插入图片描述
  4. 使用时解构出来
    在这里插入图片描述

15.hook使用规则

1.组件外使用 x
2.if,for循环内使用 x

16.json-server和axios使用
在这里插入图片描述

17. UseMemo

  1. 对于计算数据量大的函数,当重新渲染时,函数结果不必重新执行,用于性能优化
    在这里插入图片描述
    当点击button2时,组件重新渲染,但result不会重新计算,只有点击button1时才会重新计算
  2. memo:将 memo(function APP1(){}),当子组件prop无变化时,使用memo可以阻止子组件渲染

prop的比较机制:使用Object.is,基础类型和引用类型不同
在这里插入图片描述
[]!==[]因为是不同的对象实例

在这里插入图片描述

useCallback

useCallback是React的一个Hook,用于优化性能,它可以帮助我们避免在渲染过程中不必要地创建新的函数实例。

它接受两个参数:一个是我们需要记忆化的函数,另一个是一个依赖项数组。当依赖项发生变化时,useCallback会返回一个新的记忆化函数。

useCallback的主要用途是优化性能。在React中,如果我们在组件渲染时创建函数,那么每次渲染都会创建一个新的函数实例。如果这个函数被用作子组件的props,那么即使父组件的状态或props没有变化,子组件也会因为接收到新的函数实例而重新渲染。通过使用useCallback,我们可以确保在依赖项没有变化的情况下,始终使用同一个函数实例,从而避免不必要的子组件重新渲染。

例如,以下代码创建了一个记忆化的`handleClick`函数,只有当`id`发生变化时,才会创建新的函数实例:
const handleClick = useCallback(() => {
  console.log(id);
}, [id]);
return <button onClick={handleClick}>Click me</button>;
下例中,与memo配合使子组件不重复渲染(**因为还使用上一个函数实例子组件的prop参数未发生变化)**,性能优化

在这里插入图片描述

useRequest

useRequest是ahook第三方库中提供的一个hook
在获取数据方面,可以代替useEffect

const { data, error, loading, run } = useRequest(fetchData);

// 在需要的时候调用 run 函数来触发数据请求
const handleFetchData = () => {
  run();
};

USeRequest返回五个参数,可通过解构赋值获取

  • data: 保存请求成功时的数据。
  • error: 保存请求失败时的错误信息。
  • loading: 表示当前请求是否正在加载中。
  • cancel: 用于取消当前请求的函数。
  • run: 触发请求的函数。

二、 react使用redux

在这里插入图片描述

在这里插入图片描述
在我们继续之前,你需要熟悉一些重要的 Redux 术语:

  • state
  • action,action 是一个具有 type 字段的普通 JavaScript 对象,只描述发生了什么事情,有type,payload字段
  • reducer是一个纯函数,接收当前的 state 和一个 action 对象,必要时决定如何更新状态,并返回新状态。函数签名是:(state, action) => newState。 你可以将 reducer 视为一个事件监听器,它根据接收到的 action(事件)类型处理事件。
  • dispatch,调用action
  • UseSelector:允许你从 Redux store 中选择状态并订阅其更改,代替了connect
    在这里插入图片描述

三、美团外卖项目

在这里插入图片描述

  1. 添加按钮怎么显示?
    解决方法:antd icon在这里插入图片描述
    在这里插入图片描述
  2. 滚动菜单如何实现
    解决方法:将延长的区域设置overflow:auto
  3. flex
    flex:1 不管内容多少,一般都是平分空间,空间大小都一致、
    而 flex:auto 是根据内容的大小来分,不是平的(除非内容都是一样,才平分)

完成页面制作

在这里插入图片描述

使用redux渲染页面

完成购物车功能
在这里插入图片描述

store.js
// 编写store

import { createSlice } from "@reduxjs/toolkit"
import axios from "axios"

const foodsStore = createSlice({
  name: 'foods',
  initialState: {
    // 商品列表
    foodsList: [],
    // 菜单激活下标值
    activeIndex: 0,
    // 购物车列表
    cartList: []
  },
  reducers: {
    // 更改商品列表
    setFoodsList (state, action) {
        // payload是传入的值
      state.foodsList = action.payload
    },
    changeActiveIndex(state,action){
        state.activeIndex = action.payload
    },
    addCart (state, action) {
        // 是否添加过?以action.payload.id去cartList中匹配 匹配到了 添加过
        const item = state.cartList.find(item => item.id === action.payload.id)
        if (item) {
          item.count++
        } else {
          state.cartList.push(action.payload)
        }
      },
      // count增
      increCount (state, action) {
        // 关键点:找到当前要修改谁的count id
        const item = state.cartList.find(item => item.id === action.payload.id)
        item.count++
      },
      // count减
      decreCount (state, action) {
        // 关键点:找到当前要修改谁的count id
        const item = state.cartList.find(item => item.id === action.payload.id)
        if (item.count === 0) {
          return
        }
        item.count--
      },
    clearCart(state){
        state.cartList=[];
    },
   
    
  }
})

// 异步获取部分
const { setFoodsList, changeActiveIndex, addCart, increCount, decreCount, clearCart } = foodsStore.actions
const fetchFoodsList = () => {
  return async (dispatch) => {
    // 编写异步逻辑
    const res = await axios.get('meituan/menu')
    // 调用dispatch函数提交action
    dispatch(setFoodsList(res.data))
  }
}

export { fetchFoodsList, changeActiveIndex, addCart, increCount, decreCount, clearCart }

const reducer = foodsStore.reducer

export default reducer

使用react-router-dom

  1. 制作路由表
const router = createBrowserRouter([
    {
        path:"login",
        element:<DempPage/>
    },
    {
        path:"index",
        element:<DempPage/>
    }
])
  • 声明式导航
<Link to='/index'  />
  • 编程式导航
useNavigate()
  • Routes 多个Route需要Route包起来
  • Route
  • Outle 给children占位

request请求中的url(‘xxx’)都是基于当前上级路由url的拼接,是相对路由
url(‘/xxx’)是绝对路由,根。

重定向默认路由

const router = createBrowserRouter(
[
  {
     path:"/",
     element:<App/>,
     children:
     [
       {
          path:"/",
           // replace属性表示这是一个替换操作,而不是在历史记录中添加新的条目。
           element: <Navigate to="/home" replace />
        },
       {
           path:"home",
           element:<Home/>,
            
        }
   }
]

查看评价

在这里插入图片描述

在img标签里面只设置宽度,不设置高度,图片就会等比例缩放。

封装request请求

import axios from "axios";

const api= axios.create({
    baseURL:"http://geek.itheima.net/v1_0",
    timeout:5000
})

// 请求拦截
api.interceptors.request.use((config)=>{
    return config
},(error)=>{
    return Promise.reject(error);
})

// 响应拦截
api.interceptors.response.use((response)=>{
    return response.data;
},(error)=>{
    return Promise.reject(error);
})

interface Request {
  get: (url: string) => Promise<any>;
  post: (url: string, params: any) => Promise<any>;
}

// 封装request模块
const request: Request = {
  get: (url: string) => api.get(url),
  post: (url: string, params: any) => api.post(url, { ...params })
};

// const request = (method, url, data = null) => {
//  return api({
//    method: method,
//    url: url,
//    data: data,
//    // 其他请求配置
//  })
//    .then(response => {
//      // 处理请求成功的响应
//      return response.data;
//    })
//    .catch(error => {
//     // 处理请求失败的情况
//      console.error('Request failed:', error);
//      throw error;
//    });
//};

export default request;

在这里插入图片描述

Token管理

  1. redux管理token
  2. 使用localstorag存储token,实现持久化管理
  • 20
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值