redux_舊版本

reduxjs/toolkit(RTK)是 Redux 官方團隊推出的一個工具集,旨在簡化 Redux 的使用和配置。它于 2019 年 10 月 正式發布,此文章記錄一下redux的舊版本如何使用,以及引入等等。
在這里插入圖片描述

在這里插入圖片描述
文件目錄如下:
在這里插入圖片描述

步驟

  1. 安裝依賴

    npm install redux react-redux redux-thunk
    
  2. 設置 Redux Store
    創建 store.js 文件并配置 createStore
    使用 combineReducers 合并多個 reducer。
    使用 applyMiddleware 添加 thunk 中間件。

  3. 創建 Actions
    定義 action 類型和 action 創建函數。

  4. 創建 Reducers
    根據 action 類型更新 state。

  5. 連接 React 組件到 Redux Store
    使用 Provider 組件將 store 提供給整個應用。
    使用 connect 函數將組件連接到 Redux store,并映射 state 和 dispatch 方法到組件的 props。

  6. 使用 Redux DevTools
    配置 Redux DevTools 以方便調試。

1. 安裝必要的依賴

安裝 reduxreact-reduxredux-thunk(用于處理異步操作)。

npx create-react-app redux-test
cd redux-test
npm install redux react-redux redux-thunk

2. 設置 Redux Store

創建一個 store.js 文件來配置 Redux store
applyMiddleware 用于在 Redux store 中應用中間件,中間件在 Redux 的 action 被分發到 reducer 之前攔截這些 action,可以擴展 Redux 的功能,實現諸如異步操作(使用 redux-thunk 或 redux-saga)、路由控制、日志記錄等。

applyMiddleware工作原理
1.Action 分發:
當一個 action 被分發時,它首先會被傳遞給中間件。
2.中間件鏈:
中間件按照應用的順序形成一個鏈,每個中間件可以處理 action 并決定是否繼續傳遞給下一個中間件或 reducer。
3.處理邏輯:
每個中間件可以執行自定義邏輯,例如記錄日志、處理異步操作等。
4.傳遞 Action:
最終,action 會被傳遞給 reducer 進行狀態更新

src/redux/store.js

/**
* 該文件專門用于暴露一個store對象,整個應用只有一個store對象
* */
// 引入createStore,專門用于創建redux中最為核心的 store
import { createStore,applyMiddleware } from 'redux'
// 引入總的Reducers
import Reducers from './reducers/index'// 引入redux-thunk插件,用于支持異步action
// redux-thunk 允許你返回一個函數而不是一個普通的 action 對象。 ==>體現在action的返回值上,主要處理異步action
import { thunk } from 'redux-thunk'
// 引入redux-devtools-extension插件,用于支持redux調試工具
import { composeWithDevTools } from "redux-devtools-extension"
// 暴露store
export default createStore(Reducers,composeWithDevTools(applyMiddleware(thunk)))

src/redux/reducers/index.js

combineReducers 匯總所有的reducer變為一個總的reducer

/*** 該文件用于匯總所有的reducer為一個總的reducer**/
// 引入combineReducers
import { combineReducers } from "redux";
// 引入為Count組件服務的reducer
import count from "./count";
// 引入Person組件服務的的reducer
import persons from "./person";
// 匯總所有的reducer變成一個總的reducer
export default combineReducers({count,persons
})
// export default 全局暴露的對象,可以自定義暴露對象的名稱

3. 創建 Actions

src/common/common.js

// 該模塊僅用于定義常量,其他模塊導入該常量即可
export const INCREMENT = 'INCREMENT'
export const DECREMENT = 'DECREMENT'
export const ADD_INFO = 'personInfo'

src/redux/actions/count.js

import {INCREMENT,DECREMENT} from "../../common/common";
// import store from "./store";
/*** 該文件專門為Count組件生成action對象*
**/
/**
* 同步action:action的值為Object類型的一般對象
* */
export const increment = (data)=>({type: INCREMENT, data})
export const decrement = (data)=>({type: DECREMENT, data})
/*** 異步action:action的值為函數類型,異步action中可以調用同步action,也可以自己寫異步代碼**/
export const incrementAsync = (data,time)=>{// createStore(countReducer,applyMiddleware(thunk))// applyMiddleware中可以傳入多個中間件,中間件是一個函數,該函數的參數是store,所以此處無需傳入storereturn (dispatch)=>{// console.log(dispatch);setTimeout(()=>{// store.dispatch(incrementAction(data))dispatch(increment(data))},time)}
}

src/redux/actions/person.js

import { ADD_INFO } from "../../common/common";
export const addPerson = (personObj)=>({type:ADD_INFO,personObj})

4. 創建 Reducers

創建 countReducer.jspersonReducer.js 文件來處理 actions 并更新 state。
src/redux/reducers/count.js

/*** 1.該文件適用于創建一個為Count組件服務的redux模塊中的reducer,reducer的本質是一個函數* 2.reducer函數會接到兩個參數,分別為:之前的狀態(preState),動作對象(action)* **/
import {INCREMENT,DECREMENT} from "../../common/common";let initialState = 0; // 數據初始化
export default function countReducer(preState =initialState, action) {// 從action對象中獲取:type,datalet { type, data } = action// console.log(preState,action); // 初次獲取0,"@@redux/INITx.1.n.3.n.9"// 根據type決定如何加工數據switch (type){case INCREMENT:// console.log(preState);return preState + data*1;case DECREMENT:return preState - data*1;default:return preState;// 初始化數據·}
}

src/redux/reducers/person.js

Redux 的 reducer 必須是純函數,這意味著它不能修改傳入的參數(即 preState),而是必須返回一個新的狀態對象。

純函數的定義:

  • 不能改變傳遞過來的參數的原始值
  • 只能通過返回值返回結果
  • 狀態不可變性
// 數據參數
import { ADD_INFO } from "../../common/common"
const initPersonInfo =[] // 初始化列表數據
const personReducer = (preState=initPersonInfo,action)=>{let {type,personObj} = action // 此處解構switch (type){case ADD_INFO: // 若是添加數據// preState.unshift(personObj) // 修改的原數組,導致preState參數被改寫了,       // personReducer就不是純函數;且preState的指向地址沒有發生變化,所以不會引起界面更新// return preState // vue中也是淺拷貝,但是vue中會進行深拷貝,所以界面更新// react 不會引起界面更新,因為指向地址并沒有發生變化;--淺拷貝--修改引用指針return [personObj,...preState] // 淺拷貝,此時preState指向新的地址,界面更新 // 界面的更新比較的是兩個對象的存儲位置,淺比較default:return preState}
}
// 純函數的定義:1.不能改變 傳遞過來的參數 的原始值 2.只能通過返回值返回結果
// 不管調用多少次,都只會返回一個結果
export  default personReducer
// export default 語句的語法不允許直接在 export default 后面使用 const 或 let 聲明變量。
// export default 語句可以直接導出一個表達式或一個函數,但不能直接導出一個帶有 const 或 let 聲明的變量。

export default 語句可以直接導出一個表達式或一個函數,但不能直接導出一個帶有 const 或 let 聲明的變量。

5. 連接 React 組件到 Redux Store

src/App.jsx

import React, {Component} from 'react';
// 引入容器組件
import Count from './container/Count/index'
import Person from './container/Person/index'
// 引入store;傳遞給容器組件
class App extends Component {render() {return (<div><Count/><Person/></div>);}
}
export default App;

src/index.js

// 引入核心庫
import React from 'react';
// 創建根節點
import { createRoot } from 'react-dom/client';
import store from "./redux/store";
// 使用Provider組件, 將store傳遞給APP組件,全局狀態管理
import { Provider } from "react-redux"
// 引入文件
import App from './App';
// 創建容器
const container = document.getElementById('root'); // 外殼
const root = createRoot(container); // 創建根節點
root.render(/* 此處需要Provider包裹App,讓App所有的后代容器組件都能接收到store */<Provider store={store}><App /></Provider>
);

src/container/Count/index.jsx
connect 作用:

  1. 連接組件到 Redux Store:
    connect 函數將 React 組件與 Redux store 連接起來,使得組件能夠訪問 store 中的狀態和分發 actions。
  2. 傳遞狀態到組件:
    通過 mapStateToProps 函數,將 Redux store 中的狀態映射到組件的 props。
  3. 傳遞 dispatch 方法到組件:
    通過 mapDispatchToProps 函數,將 dispatch 方法映射到組件的 props,使得組件能夠分發 actions。
  4. 優化渲染性能:
    connect 會自動處理組件的訂閱和取消訂閱,確保組件只在相關狀態變化時重新渲染。

mapStateToProps

  1. mapStateToProps函數 返回的是一個對象;
  2. 返回的對象中的key就作為UI組件props的key,value就作為傳遞UI組件props的value
  3. mapStateToProps用于傳遞狀態

mapStateToDispatch

  1. mapStateToDispatch函數 返回的是一個對象;
  2. 返回的對象中的key就作為UI組件props的key,value就作為傳遞UI組件props的value
  3. mapStateToDispatch用于傳遞操作狀態的方法
// connect()(CountUI) ==> 容器container
// 使用connect()()創建并暴露一個Count的容器組件
export default connect(mapStateToProps, mapDispatchToProps)(CountUI);
import React,{Component} from "react";
/*** 引入react-redux中connect函數,連接 UI組件和redyx(store)**/
import { connect } from "react-redux";
// store通過Provider傳遞引入
// 引入action
import {increment,decrement,incrementAsync} from "../../redux/actions/count"
// 容器通過 store 獲取狀態數據 ,傳遞給UI組件,UI組件通過props獲取
class Count extends Component{incrementNum = ()=>{// 函數let { value } = this.selectNumthis.props.increment(value)}decrementNum = ()=>{// 函數let { value } = this.selectNumthis.props.decrement(value)}// 奇數時加incrementOddNum = ()=>{// 函數let { value } = this.selectNumlet  count  = this.props.countif(count % 2 !== 0){this.props.increment(value)}}incrementAsync = ()=>{// 函數let { value } = this.selectNum // 字符串形式需要轉換,否則默認會字符串拼接this.props.incrementAsync(value,500)}render(){return(<div><h2>我是Count組件</h2><h1>求和的數值:{this.props.count}</h1><select ref={(c) => {this.selectNum = c}}><option value="1">1</option><option value="2">2</option><option value="3">3</option></select><button onClick={this.incrementNum}>+</button><button onClick={this.decrementNum}>-</button><button onClick={this.incrementOddNum}>求和為基數時再加+</button><button onClick={this.incrementAsync}>異步再加+</button></div>)}
}export default connect(state=>{// Uncaught Error: Objects are not valid as a React child (found: object with keys {countNum}). If you meant to render a collection of children, use an array instead.return { count:state.count} // 映射到UI組件的props,返回的數值必須是一個對象且需要取準確的對象,store 統一管理數據},{increment, decrement, incrementAsync}
)(Count)

src/container/Person/index.jsx

import React, {Component} from 'react';
import {addPerson} from '../../redux/actions/person'
import {connect} from 'react-redux'
// 使用nanoid 生成唯一id
import {nanoid} from "nanoid";
class Person extends Component {// 在類組件中,方法默認不會自動綁定 this。// 在構造函數中手動綁定 this// constructor(props) {//     super(props);//     this.addUserInfo = this.addUserInfo.bind(this); // 手動綁定this// }// addUserInfo  (){//     console.log(this.nameNode.value,this.ageNode.value,6665)// }// 使用箭頭函數來自動綁定 this。addUserInfo = ()=>{let name = this.nameNode.valuelet age = this.ageNode.valuelet id = nanoid()this.props.addPerson({id,name,age}) // 傳遞參數this.nameNode.value = ''this.ageNode.value = ''console.log(this.props)}render() {return (<div><h2>我是person組件</h2><input ref={c=>this.nameNode = c} type="text" placeholder="請輸入姓名" /><input ref={c=>this.ageNode = c} type="text" placeholder="請輸入年齡" /><button onClick={this.addUserInfo}>添加個人信息</button><ul>{ // 需要花括號遍歷數組this.props.persons.map((item)=>{return <li key={item.id}>id:{nanoid()}-姓名:{item.name} - 年齡:{item.age}</li>})}</ul></div>);}
}
export default connect(state=>({ persons:state.persons}),{addPerson})(Person)

6. 使用 Redux DevTools

參考鏈接:https://blog.csdn.net/pikaqiu_komorebi/article/details/145908046

自用

同步action,是指action的值為Object類型的一般對象。

異步action,是指action的值為函數 =?主要是因為函數能開啟異步任務。

const a = b?({data:b})

求和案例_redux精簡版
  1. 去除Count組件自身的狀態

  2. src下建
    -redux ( -store.js -count_reducer.js )

  3. store.js:
    1)reducer本質就是一個函數,接受:preState,action,返回加工后的狀態
    2)reducer有兩個作用:初始化狀態,加工狀態
    3)reducer被第一次調用時,是store自動觸發的,傳遞prestate是undefined

  4. count_reducer.js

     1)reducer本質就是一個函數,接受:preState,action,返回加工后的狀態2)reducer有兩個作用:初始化狀態,加工狀態3)reducer被第一次調用時,是store自動觸發的,傳遞prestate是undefined
    
  5. index.js中檢測store中狀態的改變,一旦發生改變重新渲染

// 監聽redux中狀態的改變,如redux的狀態發生了改變,重新渲染App組件store.subscribe(()=>{root.render(<App />); // 渲染應用})

備注:redux只負責管理狀態,至于狀態的改變驅動著頁面的展示,需要自己去寫

求和案例_redux異步action 版
  1. 明確:延遲的動作不想交給組件的自身,交給action ? 異步動作

  2. 何時需要異步action:想要對狀態進行操作,但是具體的數據靠異步任務返回(非必須)

  3. 具體編碼:

    1)yarn add redux-thunk,并配置在store中;使用redux的中間件 applyMiddleware ,用于添加中間件redux-thunk功能。2)創建action 的函數不再返回一般對象,而是一個函數,該函數中寫異步任務3)異步任務有結果后,分發一個同步的action 去真正操作數據
    
  4. 備注:異步action不是必須要寫的,完全可以自己等待異步任務的結果再去分發同步action

求和案例_react-redux基本使用
  1. 明確兩個概念

    1)UI組件:不能使用任何redux的api,只負責頁面的呈現、交互等2)容器組件:負責和redux通信,并將結果交給UI組件
    
  2. 如何創建一個容器組件 — — — 靠react-redux的connect函數

    connect( mapStateToProps,mapDispatchToProps )( UI組件 )- mapStateToProps:映射狀態,返回值是一個對象- mapStateToProps:映射操作狀態的方法,返回值是一個對象UI組件通過props獲取數據和方法;容器組件通過mapStateToProps,mapDispatchToProps傳遞
    
  3. 備注1:容器組件中的store是靠APP的props傳進去的,而不是在容器中直接引入

  4. 備注2:mapDispatchToProps,也可以是一個對象,redux-redux內部調用分發action

  5. 備注3:容器組件能夠自動檢測store數據的變化,可去除store.subscribe(()?{})方法

  6. Provider能夠給APP中所有的容器傳遞store,無需手動對容器組件傳遞store對象

  7. 合并文件,將容器組件和UI組件放到一起

求和案例_react-redux優化
  1. 容器組件和UI組件混成一個文件
  2. 無需手動給容器組件傳遞store,在index.js中給包裹一個即可。
// 引入核心庫
import React from 'react';
// 創建根節點
import { createRoot } from 'react-dom/client';
import store from "./redux/store";
import { Provider } from "react-redux"
// 引入文件
import App from './App';
// 創建容器
const container = document.getElementById('root'); // 外殼
const root = createRoot(container); // 創建根節點root.render(<Provider store={store}><App /></Provider>
); 
  1. 使用了react-redux后不用自己監測redux中狀態的改變,容器組件可自動監測
  2. mapStateToDispatch也可以簡單的寫成一個action對象,redux-redux可內部調用分發action
  3. 一個組件要和redux “打交道” 要經過哪幾步
    1)定義好UI組件——不暴露
    2)引入connect生成容器組件,并暴露,寫法如下
    3)在UI組件中通過this.props.xxxx讀取狀態和操作方法
connect(state?({key:value}), // 映射狀態;value數值要根據總的Reducers取值(key:xxxAction) // 映射操作狀態的方法 
)(UI組件)
求和案例_react-redux數據共享版
  1. 定義一個Person組件,和Count組件通過redux共享數據;
  2. 為Person組件編寫:reducer、action、配置common常量
  3. 重點:Person的Reducer和Count的Reducer要使用combineReducers進行合并,合并后的總狀態是一個對象
// 引入createStore,專門用于創建redux中最為核心的 store
import { createStore,applyMiddleware,combineReducers } from 'redux'
// 引入為Count組件服務的reducer
import countReducer from "./reducers/count"
import personReducer from "./reducers/person"
// 引入redux-thunk插件,用于支持異步action
import { thunk } from 'redux-thunk'
// combineReducers匯總所有的reducer變為一個總的reducer
const allReducers = combineReducers({countNum:countReducer,addPerson:personReducer
})
// 暴露store
export default createStore(allReducers,applyMiddleware(thunk))
  1. 交給store的是總reducer,最后注意在組件中取出狀態的時候,取到位
求和案例_react-redux最終版
  1. 所有變量名稱盡量觸發對象的簡寫形式
  2. reducers文件夾中,編寫index.js專門用于匯總并暴露所有的reducer

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/73093.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/73093.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/73093.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MySQL:SQL優化實際案例解析(持續更新)

文章目錄 一、MySQL&#xff1a;SQL優化1、時間格式化問題&#xff08;字符串&#xff09;2、in/inner join的問題 一、MySQL&#xff1a;SQL優化 1、時間格式化問題&#xff08;字符串&#xff09; -- 優化前 SELECT * FROM test_table WHERE date_format( begin_time, %Y-%…

【含文檔+PPT+源碼】基于Python的美食數據的設計與實現

項目介紹 本課程演示的是一款基于Python的美食數據分析系統&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Java 學習者。 包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 帶你從零開始部署運行本套系統 該項目附帶的源碼…

vue調整表格樣式之深度修改

舉例&#xff1a; <div class"grid-item"><h3>日數據</h3><el-table :data"dailyData" v-loading"loading"><el-table-column label"銷售姓名" align"center" prop"salesName" />…

【Go每日一練】統計字符出現的次數

&#x1f47b;創作者&#xff1a;丶重明 &#x1f47b;創作時間&#xff1a;2025年3月9日 &#x1f47b;擅長領域&#xff1a;運維 目錄 1.&#x1f636;?&#x1f32b;?題目&#xff1a;統計字符出現的次數2.&#x1f636;?&#x1f32b;?代碼中可用的資源3.&#x1f636;…

uniapp在APP平臺(Android/iOS)選擇非媒體文件

TOC 背景 在我們APP開發過程中&#xff0c;經常會有這樣一個需求場景&#xff1a;從手機中選擇文件然后進行上傳&#xff0c;這些文件主要分為兩類&#xff0c;媒體文件和非媒體文件。而媒體文件選擇在APP平臺我們可以使用uni.chooseImage和uni.chooseVideo這兩個API來實現。…

【eNSP實戰】配置交換機端口安全

拓撲圖 目的&#xff1a;讓交換機端口與主機mac綁定&#xff0c;防止私接主機。 主機PC配置不展示&#xff0c;按照圖中配置即可。 開始配置之前&#xff0c;使用PC1 ping 一遍PC2、PC3、PC4、PC5&#xff0c;讓交換機mac地址表刷新一下記錄。 LSW1查看mac地址表 LSW1配置端…

卡爾曼濾波算法從理論到實踐:在STM32中的嵌入式實現

摘要&#xff1a;卡爾曼濾波&#xff08;Kalman Filter&#xff09;是傳感器數據融合領域的經典算法&#xff0c;在姿態解算、導航定位等嵌入式場景中廣泛應用。本文將從公式推導、代碼實現、參數調試三個維度深入解析卡爾曼濾波&#xff0c;并給出基于STM32硬件的完整工程案例…

Redis----大key、熱key解決方案、腦裂問題

文章中相關知識點在往期已經更新過了&#xff0c;如果有友友不理解可翻看往期內容 出現腦裂問題怎么保證集群還是高可用的 什么是腦裂問題 腦裂說的就是當我們的主節點沒有掛&#xff0c;但是因為網絡延遲較大&#xff0c;然后和主節點相連的哨兵通信較差&#xff0c;之后主…

python總結(3)

創建自定義類 終于要創建自定義類了!下面是一個簡單的示例: class Person:def set_name(self, name):self.name namedef get_name(self):return self.namedef greet(self):print("Hello, world! Im {}.".format(self.name))這個示例包含三個方法定義&#xff0c;它…

word畢業論文“et al.”替換為“等”——宏

Sub 中文參考文獻改等()中文參考文獻改等 宏Selection.Find.ClearFormattingSelection.Find.Replacement.ClearFormattingWith Selection.Find.Text "([一-龥], )et al.".Replacement.Text "\1等.".Forward True.Wrap wdFindContinue.Format False.Ma…

網絡編程-----服務器(多路復用IO 和 TCP并發模型)

一、單循環服務器模型 1. 核心特征 while(1){newfd accept();recv();close(newfd);}2. 典型應用場景 HTTP短連接服務&#xff08;早期Apache&#xff09;CGI快速處理簡單測試服務器 3. 綜合代碼 #include <stdio.h> #include <sys/types.h> /* See NO…

typora高亮方案+鼠標側鍵一鍵改色

引言 在typora里面有一個自定義的高亮, <mark></mark>>但是單一顏色就太難看了, 我使用人工智能, 搜索全網藝術家, 匯集了幾種好看的格式,并且方便大家側鍵一鍵 調用, 是不是太方便啦 ! 示例 午夜模式 春意盎然 深海藍調 石墨文檔 秋日暖陽 蜜桃宣言 使用方法 …

swift -(5) 匯編分析結構體、類的內存布局

一、結構體 在 Swift 標準庫中&#xff0c;絕大多數的公開類型都是結構體&#xff0c;而枚舉和類只占很小一部分 比如Bool、 Int、 Double、 String、 Array、 Dictionary等常見類型都是結構體 ① struct Date { ② var year: Int ③ var month: Int ④ …

從零開始學機器學習——初探分類器

首先給大家介紹一個很好用的學習地址:https://cloudstudio.net/columns 在上一節中,我們已經完成了對所有經過均衡和清洗的菜品數據的準備工作。接下來,我們將考慮使用多種算法,也就是不同的分類器,來構建模型。我們將利用這個數據集和各種分類器,基于一組特定的配料,預…

黑色RGB是什么

>好的&#xff0c;用戶現在問的是“黑色rgb是什么”。我需要先理解用戶的問題。之前用戶在使用MATLAB調整網格線顏色時&#xff0c;可能看到了默認顏色是黑色&#xff0c;或者之前我提到過默認顏色是[0.15 0.15 0.15]&#xff0c;而用戶可能現在想知道黑色的RGB值具體是什么…

做到哪一步才算精通SQL

做到哪一步才算精通SQL-Structured Query Language 數據定義語言 DDL for StructCREATE&#xff1a;用來創建數據庫、表、索引等對象ALTER&#xff1a;用來修改已存在的數據庫對象DROP&#xff1a;用來刪除整個數據庫或者數據庫中的表TRUNCATE&#xff1a;用來刪除表中所有的行…

《深度解析DeepSeek-M8:量子經典融合,重塑計算能效格局》

在科技飛速發展的今天&#xff0c;量子計算與經典算法的融合成為了前沿領域的焦點。DeepSeek-M8的“量子神經網絡混合架構”&#xff0c;宛如一把鑰匙&#xff0c;開啟了經典算法與量子計算協同推理的全新大門&#xff0c;為諸多復雜問題的解決提供了前所未有的思路。 量子計算…

解決電腦問題(2)——主板問題

當電腦主板出現問題時&#xff0c;可以嘗試以下解決方法&#xff1a; 外觀檢查與清潔 檢查硬件連接&#xff1a;仔細查看主板上的各種硬件連接&#xff0c;包括 CPU、內存、顯卡、硬盤、電源等的連接線是否松動或損壞。確保所有插頭都牢固地插入相應的插槽中&#xff0c;如有松…

Java 大視界 -- Java 大數據在智能家居能源管理與節能優化中的應用(120)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

【網絡】TCP常考知識點詳解

TCP報文結構 TCP報文由**首部&#xff08;Header&#xff09;和數據&#xff08;Data&#xff09;**兩部分組成。首部包括固定部分&#xff08;20字節&#xff09;和可選選項&#xff08;最多40字節&#xff09;&#xff0c;總長度最大為60字節。 1. 首部固定部分 源端口&…