react學習筆記4——React UI組件庫與redux

流行的開源React UI組件庫

material-ui(國外)

  1. 官網: http://www.material-ui.com/#/
  2. github: GitHub - mui/material-ui: Material UI: Comprehensive React component library that implements Google's Material Design. Free forever.

ant-design(國內螞蟻金服)

  1. 官網: Ant Design - 一套企業級 UI 設計語言和 React 組件庫
  2. Github: GitHub - ant-design/ant-design: An enterprise-class UI design language and React UI library

redux

redux理解

學習文檔

  1. 英文文檔: Redux - A JS library for predictable and maintainable global state management | Redux
  2. 中文文檔: Redux | Redux 中文文檔
  3. Github: GitHub - reduxjs/redux: A JS library for predictable global state management

redux是什么

  1. redux是一個專門用于做狀態管理JS(不是react插件庫)
  2. 它可以用在react, angular, vue等項目中, 但基本與react配合使用。
  3. 作用: 集中式管理react應用中多個組件共享的狀態。

什么情況下需要使用redux

  1. 某個組件的狀態,需要讓其他組件可以隨時拿到(共享)。
  2. 一個組件需要改變另一個組件的狀態(通信)。
  3. 總體原則:能不用就不用, 如果不用比較吃力才考慮使用。

?redux工作流程

redux的三個核心概念

action

  1. 動作的對象
  2. 包含2個屬性
    1. type:標識屬性, 值為字符串, 唯一, 必要屬性
    2. data:數據屬性, 值類型任意, 可選屬性
  3. 例子:{ type:?'ADD_STUDENT',data:{name:?'tom',age:18} }

reducer

  1. 用于初始化狀態、加工狀態。
  2. 加工時,根據舊的stateaction?產生新的state純函數

store

  1. stateactionreducer聯系在一起的對象
  2. 如何得到此對象?

????????????????import {createStore} from 'redux'

????????????????import reducer from './reducers'

????????????????const store = createStore(reducer)

  1. 此對象的功能?

? ? ? ? ? ? ? ? 1.getState(): 得到state

? ? ? ? ? ? ? ? 2.dispatch(action): 分發action, 觸發reducer調用, 產生新的state

? ? ? ? ? ? ? ? 3.subscribe(listener): 注冊監聽, 當產生了新的state時, 自動調用

redux的核心API

??????????????createstore()

作用:創建包含指定reducer的store對象

?????store對象

  1. 作用: redux庫最核心的管理對象
  2. 它內部維護著:

????????????????1.state

? ? ? ? ? ? ? ? 2.reducer

??????3.核心方法:

? ? ? ? ? ? ? ?1.getState()

? ? ? ? ? ? ? ?2.dispatch(action)

? ? ? ? ? ? ? ?3.subscribe(listener)

? ? ? 4.具體編碼:

????????1.store.getState()

????????2.store.dispatch({type:'INCREMENT', number})

? ? ? ? 3.store.subscribe(render)

applyMiddleware()

作用:應用上基于redux的中間件(插件庫)

combineReducers()

作用:合并多個reducer函數

使用redux編寫應用

redux異步編程

理解:

  1. redux默認是不能進行異步處理的,
  2. 某些時候應用中需要在redux中執行異步任務(ajax, 定時器)

使用異步中間件

npm install --save redux-thunk

react-redux

?react-redux模型

?

理解

  1. 一個react插件庫
  2. 專門用來簡化react應用中使用redux

react-Redux將所有組件分成兩大類

  1. UI組件
  2. 容器組件

? ? ? ? 1.負責管理數據和業務邏輯,不負責UI的呈現

? ? ? ? 2.使用?Redux 的?API

? ? ? ? 3.一般保存在containers文件夾下

相關API

  1. Provider:讓所有組件都可以得到state數據

2.connect:用于包裝 UI 組件生成容器組件

3.mapStateToprops:將外部的數據(即state對象)轉換為UI組件的標簽屬性

4.mapDispatchToProps:將分發action的函數轉換為UI組件的標簽屬性

使用上redux調試工具

安裝chrome瀏覽器插件

下載工具依賴包

npm install --save-dev redux-devtools-extension

?redux插件常用部分

純函數和高階函數

純函數

  1. 一類特別的函數: 只要是同樣的輸入(實參),必定得到同樣的輸出(返回)
  2. 必須遵守以下一些約束??
      1. 不得改寫參數數據
      2. 不會產生任何副作用,例如網絡請求,輸入和輸出設備
      3. 不能調用Date.now()或者Math.random()等不純的方法??
  3. reduxreducer函數必須是一個純函數

高階函數

  1. 理解: 一類特別的函數

? ? ? ? ? ? ? ?1.情況1: 參數是函數

? ? ? ? ? ? ? ?2.情況2: 返回是函數

? ? ? 2.常見的高階函數:

? ? ? ? ? ? ? ? 1.定時器設置函數

? ? ? ? ? ? ? ? 2.數組的forEach()/map()/filter()/reduce()/find()/bind()

? ? ? ? ? ? ? ? 3.promise

? ? ? ? ? ? ? ? 4.react-redux中的connect函數

? ? ? ?3.作用: 能實現更加動態, 更加可擴展的功能

相關代碼:

主要文件:index.js, App.jsx, redux文件, components文件, pages文件,有相同代碼

純react版

App.jsx

import React, { Component } from "react";
import Count from './components/Count'
export default class App extends Component {render() {return <div><Count/></div>;}
}

components/Count/index.jsx

import React, { Component } from 'react'export default class Count extends Component {state = {count:0}// 加法increment=()=>{const {value} = this.selectNumberconst {count} = this.statethis.setState({count:count+value*1 //強制類型轉換,value是一個字符串})}// 減法decrement=()=>{const {value} = this.selectNumberconst {count} = this.statethis.setState({count: count-value*1})}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberconst {count} = this.stateif(count %2 != 0){this.setState({count: count+value*1})}}//異步加incrementAsync=()=>{const {value} = this.selectNumberconst {count} = this.statesetTimeout(()=>{this.setState({count: count+value*1})}, 500)}render() {return (<div><h1>當前求和為:{this.state.count}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}

redux精簡版

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import store from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
// 將這個App重新調用一下render
// 由于DOM的diff算法在,所以不會引起頁面的大部分重繪與重排
store.subscribe(() => {root.render(<App />);
});

App.jsx

import React, { Component } from "react";
import Count from './components/Count'
export default class App extends Component {render() {return <div><Count/></div>;}
}

redux/store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./count_reduce";
const store = createStore(countReducer);
// 暴露store
export default store;

redux/count_reduce.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log(preState, action, "99");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case "increment": //如果是加return preState + data;case "decrement": //如果是減return preState - data;default:return preState;}
}

components/Count/index.jsx

import React, { Component } from 'react'
// 引入store
import store from '../../redux/store'
export default class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 如果頁面很多的話,每個組件都這樣寫,redux狀態更改之后,要render頁面更新一下// componentDidMount(){//   // 檢測redux中狀態的變化,只要變化,就調用render//   store.subscribe(() =>{//     // 直接調用不起作用//     // this.render()//     // 更新state里面的狀態,但是什么都不寫//     // 只要調用了setState,緊接著就是調用render//     this.setState({})//   })// }// 加法increment=()=>{const {value} = this.selectNumberstore.dispatch({type: 'increment',data:value*1})}// 減法decrement=()=>{const {value} = this.selectNumberstore.dispatch({type: 'decrement',data:value*1})}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberconst count = store.getState()if(count %2 !== 0){store.dispatch({type: 'increment',data:value*1})}}//異步加incrementAsync=()=>{const {value} = this.selectNumbersetTimeout(()=>{store.dispatch({type: 'increment',data:value*1})}, 500)}render() {return (<div><h1>當前求和為:{store.getState()}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}

redux完整版

其他文件代碼相同:

redux

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./count_reduce";
const store = createStore(countReducer);
// 暴露store
export default store;

count_reduce.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "./constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log(preState, action, "99");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

count_action.js

/*該文件專門為Count組件生成action對象
*/
// 這樣寫會被認為是函數體的對象
export const createIncrementAction = (data) => ({ type: "increment", data });export const createDecrementAction = (data) => ({ type: "decrement", data });

constant.js

/*該模塊是用于定義action對象中type類型的常量值,目的只有一個:便于管理的同時防止程序員單詞寫錯
*/
export const INCREMENT = "increment";
export const DECREMENT = "decrement";

components/Count/index.jsx

import React, { Component } from 'react'
// 引入store,用于獲取redux中保存狀態
import store from '../../redux/store'
// 引入actionCreator,專門用于創建action對象
import {createIncrementAction,createDecrementAction} from '../../redux/count_action'
export default class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 如果頁面很多的話,每個組件都這樣寫,redux狀態更改之后,要render頁面更新一下// componentDidMount(){//   // 檢測redux中狀態的變化,只要變化,就調用render//   store.subscribe(() =>{//     // 直接調用不起作用//     // this.render()//     // 更新state里面的狀態,但是什么都不寫//     // 只要調用了setState,緊接著就是調用render//     this.setState({})//   })// }// 加法increment=()=>{const {value} = this.selectNumberstore.dispatch(createIncrementAction(value*1))}// 減法decrement=()=>{const {value} = this.selectNumberstore.dispatch(createDecrementAction(value*1))}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberconst count = store.getState()if(count %2 !== 0){store.dispatch(createIncrementAction(value*1))}}//異步加incrementAsync=()=>{const {value} = this.selectNumbersetTimeout(()=>{store.dispatch(createIncrementAction(value*1))}, 500)}render() {return (<div><h1>當前求和為:{store.getState()}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}

redux異步action

redux文件

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./count_reduce";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
// 暴露store
export default createStore(countReducer, applyMiddleware(thunk));

?count-reduce.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "./constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log(preState, action, "99");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

count_action.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "./constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });export const createDecrementAction = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};

components/Count/index.jsx

import React, { Component } from 'react'
// 引入store,用于獲取redux中保存狀態
import store from '../../redux/store'
// 引入actionCreator,專門用于創建action對象
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction
} from '../../redux/count_action'
export default class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 如果頁面很多的話,每個組件都這樣寫,redux狀態更改之后,要render頁面更新一下// componentDidMount(){//   // 檢測redux中狀態的變化,只要變化,就調用render//   store.subscribe(() =>{//     // 直接調用不起作用//     // this.render()//     // 更新state里面的狀態,但是什么都不寫//     // 只要調用了setState,緊接著就是調用render//     this.setState({})//   })// }// 加法increment=()=>{const {value} = this.selectNumberstore.dispatch(createIncrementAction(value*1))}// 減法decrement=()=>{const {value} = this.selectNumberstore.dispatch(createDecrementAction(value*1))}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberconst count = store.getState()if(count %2 !== 0){store.dispatch(createIncrementAction(value*1))}}//異步加incrementAsync=()=>{const {value} = this.selectNumber// setTimeout(()=>{store.dispatch(createIncrementAsyncAction(value*1,500))// }, 500)}render() {return (<div><h1>當前求和為:{store.getState()}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}

react-redux的基本使用

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import store from "./redux/store";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);
// 將這個App重新調用一下render
// 由于DOM的diff算法在,所以不會引起頁面的大部分重繪與重排
// 監測redux中狀態的改變,如果redux的狀態改變了,那么重新渲染App組件
store.subscribe(() => {root.render(<App />);
});

App.jsx

import React, { Component } from "react";
import Count from './containers/Count'
import store from './redux/store'
export default class App extends Component {render() {return (<div>{/* 給容器組件傳遞store */}<Count store={store} /></div>);}
}

redux文件

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./count_reduce";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
// 暴露store
export default createStore(countReducer, applyMiddleware(thunk));

count_reduce.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "./constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log(preState, action, "99");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

count_action.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "./constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });export const createDecrementAction = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};

Container/index.jsx

// 引入Count組件的UI組件
import CountUI from '../../components/Count'
// 引入store
// import store from '../../redux/store'
// 引入action
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction
} from '../../redux/count_action'
// 引入connect用于連接UI組件與redux
import {connect} from 'react-redux'// mapStateToProps函數的返回值作為狀態傳遞給了UI組件
/*1.mapStateToProps函數返回的是一個對象2.mapStateToProps函數返回的對象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value————狀態3.mapStateToProps用于傳遞狀態
*/
// 在調用mapStateToProps函數的時候,別人已經幫你調用完了store.getState(),而且把返回的狀態傳遞給了mapStateToProps函數,只需要接收遞給UI組件就行
function mapStateToProps(state){return {count: state}
}  //這樣寫相當于<CountUI n={900} />
/*1.mapDispatchToProps函數返回的是一個對象2.mapDispatchToProps函數返回的對象中的key就作為傳遞給UI組件props的key,value就作為傳遞給UI組件props的value————操作狀態的方法(dispatch)3.mapDispatchToProps用于傳遞操作狀態的方法(dispatch)
*/
function mapDispatchToProps(dispatch){return {// 通知redux執行加法jia:number=>dispatch(createIncrementAction(number)),jian:number=>dispatch(createDecrementAction(number)),jiaAsync:(number,time)=>dispatch(createIncrementAsyncAction(number,time)),}
}
// connect()的返回值是一個函數
// const CountContainer = connect()(CountUI)
// 使用connect()()創建并暴露一個Count的容器組件
// export default CountContainer
// 這個地方的父子關系不是靠標簽形成的父子關系,沒有這樣寫<CountUI a="1" />,也就傳遞不了參數,那么就將要傳遞的參數在第一個()里面傳遞
export default connect(mapStateToProps,mapDispatchToProps)(CountUI)

Components/Count/index.jsx

import React, { Component } from 'react'
// 在UI組件中看不到任何與redux相關的API
export default class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 加法increment=()=>{const {value} = this.selectNumberthis.props.jia(value*1)}// 減法decrement=()=>{const {value} = this.selectNumberthis.props.jian(value*1)}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberif(this.props.count %2 !== 0){this.props.jia(value*1)}}//異步加incrementAsync=()=>{const {value} = this.selectNumberthis.props.jiaAsync(value*1,500)}render() {// console.log('UI組件接收到的props是',this.props);return (<div><h1>當前求和為:{this.props.count}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}

react-redux優化

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import store from "./redux/store";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
// 優化2
// 誰需要store,就給那個組件傳遞
// 批量給每個容器組件都傳遞了store對象
root.render(<Provider store={store}><App /></Provider>
);

App.jsx

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

redux文件

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./count_reduce";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
// 暴露store
export default createStore(countReducer, applyMiddleware(thunk));

count_reduce.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "./constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log(preState, action, "99");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

count_action.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "./constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });export const createDecrementAction = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};

contsiners/Count/index.jsx

// 引入Count組件的UI組件
import React, { Component } from 'react'// 引入action
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction
} from '../../redux/count_action'
// 引入connect用于連接UI組件與redux
import {connect} from 'react-redux'// 定義UI組件
class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 加法increment=()=>{const {value} = this.selectNumberthis.props.jia(value*1) //這個地方接收到的是一個函數}// 減法decrement=()=>{const {value} = this.selectNumberthis.props.jian(value*1)}//奇數在加incrementIfOdd=()=>{const {value} = this.selectNumberif(this.props.count %2 !== 0){this.props.jia(value*1)}}//異步加incrementAsync=()=>{const {value} = this.selectNumberthis.props.jiaAsync(value*1,500)}render() {// console.log('UI組件接收到的props是',this.props);return (<div><h1>當前求和為:{this.props.count}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}// 使用connect()()創建并暴露一個Count的容器組件
// 語法精簡與API精簡
export default connect(state =>  ({count: state}),// mapDispatchToProps的一般寫法
//   dispatch =>({
//     // 通知redux執行加法
//    jia:number=>dispatch(createIncrementAction(number)),
//    jian:number=>dispatch(createDecrementAction(number)),
//    jiaAsync:(number,time)=>dispatch(createIncrementAsyncAction(number,time)),
//  })// 優化1// mapDispatchToProps的簡寫{jia: createIncrementAction, //只需要寫到action,就會自動調用dispatchjian: createDecrementAction,jiaAsync: createIncrementAsyncAction}
)(Count)

react-redux數據共享版

App.jsx

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

redux文件

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware, combineReducers } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./reducers/count";
// 引入為Count組件服務的reducer
import personReducer from "./reducers/person";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
//多個reducer工作的時候,redux要管理多個狀態,最好的辦法是用一個對象去存儲所有的東西,如果用數組存儲,不好區分這是哪一個reducer
// 匯總所有的reducer變為一個總的reducer
const allReducer = combineReducers({he: countReducer,rens: personReducer,
});
// 暴露store
export default createStore(allReducer, applyMiddleware(thunk));

constant.js

/*該模塊是用于定義action對象中type類型的常量值,目的只有一個:便于管理的同時防止程序員單詞寫錯
*/
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
export const ADD_PERSON = "ADD_PERSON";

reducers文件

count.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "../constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log("countReducer@#@#@#");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

perosn.js

import { ADD_PERSON } from "../constant";
// 初始化人的列表
const initState = [{ id: "001", name: "Tom", age: 18 }];
export default function personReducer(preState = initState, action) {console.log("personReducer@#@#@#");const { type, data } = action;switch (type) {case ADD_PERSON: //若是添加一個人return [data, ...preState];default:return preState;}
}

actions文件

count.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "../constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });export const createDecrementAction = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};

person.js

import { ADD_PERSON } from "../constant";
// 創建增加一個人的action對象
export const createAddPersonAction = (personObj) => ({type: ADD_PERSON,data: personObj,
});

containers文件

Person/index.jsx

import React, { Component } from 'react'
import { nanoid } from 'nanoid'
import { connect } from 'react-redux'
import { createAddPersonAction } from '../../redux/actions/person'
class Person extends Component {addPerson = () => {const name = this.nameNode.valueconst age = this.ageNode.value// console.log(name,age);const personObj = { id: nanoid(), name, age }this.props.jiaYiRen(personObj)this.nameNode.value = ''this.ageNode.value = ''}render() {return (<div><h2>我是Person組件,上方組件求和為:{this.props.he}</h2><input ref={c => this.nameNode = c} type="text" placeholder="輸入名字" /><input ref={c => this.ageNode = c} type="text" placeholder="輸入年齡" /><button onClick={this.addPerson}>添加</button><ul>{this.props.yiduiren.map(p =><li key={p.id}>{p.name}———{p.age}</li>)}</ul></div>)}
}
// 默認導出只有一個
// 容器組件里面有所有redux的狀態
export default connect(state => ({ yiduiren: state.rens, he: state.he }), //映射狀態{jiaYiRen: createAddPersonAction //映射操作狀態的方法}
)(Person)

Count/index.jsx

// 引入Count組件的UI組件
import React, { Component } from 'react'// 引入action
import {createIncrementAction,createDecrementAction,createIncrementAsyncAction
} from '../../redux/actions/count'
// 引入connect用于連接UI組件與redux
import { connect } from 'react-redux'// 定義UI組件
class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 加法increment = () => {const { value } = this.selectNumberthis.props.jia(value * 1) //這個地方接收到的是一個函數}// 減法decrement = () => {const { value } = this.selectNumberthis.props.jian(value * 1)}//奇數在加incrementIfOdd = () => {const { value } = this.selectNumberif (this.props.count % 2 !== 0) {this.props.jia(value * 1)}}//異步加incrementAsync = () => {const { value } = this.selectNumberthis.props.jiaAsync(value * 1, 500)}render() {// console.log('UI組件接收到的props是',this.props);return (<div><h2>我是Count組件,下方組件總人數為:{this.props.renshu}</h2><h1>當前求和為:{this.props.count}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}// 使用connect()()創建并暴露一個Count的容器組件
// 語法精簡與API精簡
export default connect(// 現在redux管理的是一個對象,所以state是一個對象,需要取出里面的數值state => ({ count: state.he, renshu: state.rens.length }),// mapDispatchToProps的簡寫{jia: createIncrementAction, //只需要寫到action,就會自動調用dispatchjian: createDecrementAction,jiaAsync: createIncrementAsyncAction}
)(Count)

react-redux_開發者工具的使用

redux文件

stoe.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware, combineReducers } from "redux";
// 引入為Count組件服務的reducer
import countReducer from "./reducers/count";
// 引入為Count組件服務的reducer
import personReducer from "./reducers/person";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
// 引入redux-devtools-extension
import { composeWithDevTools } from "redux-devtools-extension";
//多個reducer工作的時候,redux要管理多個狀態,最好的辦法是用一個對象去存儲所有的東西,如果用數組存儲,不好區分這是哪一個reducer
// 匯總所有的reducer變為一個總的reducer
const allReducer = combineReducers({he: countReducer,rens: personReducer,
});
// 暴露store
export default createStore(allReducer,composeWithDevTools(applyMiddleware(thunk))
);

reducers

count.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "../constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log("countReducer@#@#@#");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

person.js

import { ADD_PERSON } from "../constant";
// 初始化人的列表
const initState = [{ id: "001", name: "Tom", age: 18 }];
export default function personReducer(preState = initState, action) {console.log("personReducer@#@#@#");const { type, data } = action;switch (type) {case ADD_PERSON: //若是添加一個人// 錯誤的寫法,// 這樣寫會破壞一個規則,你的reducer就不是一個純函數了// preState.unshift(data);  //這種寫法影響的是原數組,改寫了參數數據,此處不可以這樣寫,這樣會導致preState被改寫了,personReducer就不是純函數了// 會影響redux不能識別狀態的改變// console.log(preState);// return preState;return [data, ...preState]; //拿到之前的人,放到了一個新的數組,這個數組和preState不是同一個數組// redux底層會判斷操作的preState與返回的preState是不是一個,判斷的是地址值,是不是指向了同一個default:return preState;}
}
// 舉例,即便是推進去了一個數據,但是他們的地址值都是一樣的
// let arr = [1, 3, 5, 7, 9];
// arr.push(10);
// 第一次調用和第二次調用的返回值不一樣
// function demo(a) {
//   // a = 9  改寫了參數就不純函數了
//   return Math.random() + a;
// }

actions

count.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "../constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const createIncrementAction = (data) => ({ type: INCREMENT, data });export const createDecrementAction = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const createIncrementAsyncAction = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(createIncrementAction(data));}, time);};
};

person.js

import { ADD_PERSON } from "../constant";
// 創建增加一個人的action對象
export const createAddPersonAction = (personObj) => ({type: ADD_PERSON,data: personObj,
});

最終版

index.js

import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import store from "./redux/store";
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
// 優化2
// 誰需要store,就給那個組件傳遞
// 批量給每個容器組件都傳遞了store對象
root.render(// 此處需要用Provider包裹App,目的是讓App所有后代容器組件都能接收到store<Provider store={store}><App /></Provider>
);

App.jsx

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

redux文件

store.js

/*該文件用于暴露一個store對象,整個應用只有一個store對象
*/
//引入createStore,專門用于創建redux中最為核心的store對象
import { createStore, applyMiddleware, combineReducers } from "redux";
// 引入匯總之后的reducer
import reducer from "./reducers";
// const store = createStore(countReducer);
// 引入redux-thunk,用于支持異步action
import { thunk } from "redux-thunk";
// 引入redux-devtools-extension
import { composeWithDevTools } from "redux-devtools-extension";// 暴露store
export default createStore(reducer,composeWithDevTools(applyMiddleware(thunk))
);

constant.js

/*該模塊是用于定義action對象中type類型的常量值,目的只有一個:便于管理的同時防止程序員單詞寫錯
*/
export const INCREMENT = "increment";
export const DECREMENT = "decrement";
export const ADD_PERSON = "ADD_PERSON";

reducers文件

count.js

/*1.該文件是用于創建一個為Count組件服務的reducer,reducer的本質就是一個函數2.reducer函數會接收到兩個參數,分別為:之前的狀態(preState),動作對象(action)
*/
import { INCREMENT, DECREMENT } from "../constant.js";
const initState = 0; //初始化狀態
export default function countReducer(preState = initState, action) {console.log("countReducer@#@#@#");if (preState === undefined) preState = 0;// 從action對象中獲取:type、dataconst { type, data } = action;//根據type決定如何加工數據switch (type) {case INCREMENT: //如果是加return preState + data;case DECREMENT: //如果是減return preState - data;default:return preState;}
}

person.js

import { ADD_PERSON } from "../constant";
// 初始化人的列表
const initState = [{ id: "001", name: "Tom", age: 18 }];
export default function personReducer(preState = initState, action) {console.log("personReducer@#@#@#");const { type, data } = action;switch (type) {case ADD_PERSON: //若是添加一個人// 錯誤的寫法,// 這樣寫會破壞一個規則,你的reducer就不是一個純函數了// preState.unshift(data);  //這種寫法影響的是原數組,改寫了參數數據,此處不可以這樣寫,這樣會導致preState被改寫了,personReducer就不是純函數了// 會影響redux不能識別狀態的改變// console.log(preState);// return preState;return [data, ...preState]; //拿到之前的人,放到了一個新的數組,這個數組和preState不是同一個數組// redux底層會判斷操作的preState與返回的preState是不是一個,判斷的是地址值,是不是指向了同一個default:return preState;}
}
// 舉例,即便是推進去了一個數據,但是他們的地址值都是一樣的
// let arr = [1, 3, 5, 7, 9];
// arr.push(10);
// 第一次調用和第二次調用的返回值不一樣
// function demo(a) {
//   // a = 9  改寫了參數就不純函數了
//   return Math.random() + a;
// }

index.js

// 該文件用于匯總所有的reducer為一個總的reducer
// 引入combineReducers,用于匯總多個reducer
import { combineReducers } from "redux";// 引入為Count組件服務的reducer
import count from "./count";
// 引入為Person組件服務的reducer
import persons from "./person";//多個reducer工作的時候,redux要管理多個狀態,最好的辦法是用一個對象去存儲所有的東西,如果用數組存儲,不好區分這是哪一個reducer
// 匯總所有的reducer變為一個總的reducer
const allReducer = combineReducers({count,persons
});
export default allReducer;

actions

count.js

/*該文件專門為Count組件生成action對象
*/
import { INCREMENT, DECREMENT } from "../constant.js";
// import store from "./store";
// 這樣寫會被認為是函數體的對象————見demo.html解釋
// 同步action,就是指action的值為Object類型的一般對象
export const increment = (data) => ({ type: INCREMENT, data });export const decrement = (data) => ({ type: DECREMENT, data });
// 所謂的異步action就是指action的值為函數,異步action中一般都會調用同步action,異步action不是必須要用的
export const incrementAsync = (data, time) => {return (dispatch) => {setTimeout(() => {dispatch(increment(data));}, time);};
};

person.js

import { ADD_PERSON } from "../constant";
// 創建增加一個人的action對象
export const addPerson = (personObj) => ({type: ADD_PERSON,data: personObj,
});

containers文件

Person/index.jsx

import React, { Component } from 'react'
import { nanoid } from 'nanoid'
import { connect } from 'react-redux'
import { addPerson } from '../../redux/actions/person'
class Person extends Component {addPerson = () => {const name = this.nameNode.valueconst age = this.ageNode.value * 1// console.log(name,age);const personObj = { id: nanoid(), name, age }this.props.addPerson(personObj)this.nameNode.value = ''this.ageNode.value = ''}render() {return (<div><h2>我是Person組件,上方組件求和為:{this.props.count}</h2><input ref={c => this.nameNode = c} type="text" placeholder="輸入名字" /><input ref={c => this.ageNode = c} type="text" placeholder="輸入年齡" /><button onClick={this.addPerson}>添加</button><ul>{this.props.persons.map(p =><li key={p.id}>{p.name}———{p.age}</li>)}</ul></div>)}
}
// 默認導出只有一個
// 容器組件里面有所有redux的狀態
export default connect(state => ({ persons: state.persons, count: state.count }), //映射狀態{addPerson //映射操作狀態的方法}
)(Person)

Count/index.jsx

// 引入Count組件的UI組件
import React, { Component } from 'react'// 引入action
import {increment,decrement,incrementAsync
} from '../../redux/actions/count'
// 引入connect用于連接UI組件與redux
import { connect } from 'react-redux'// 定義UI組件
class Count extends Component {state = {// count: 0, //將這個地方的count去掉carName: '奔馳c63'}// 加法increment = () => {const { value } = this.selectNumberthis.props.increment(value * 1) //這個地方接收到的是一個函數}// 減法decrement = () => {const { value } = this.selectNumberthis.props.decrement(value * 1)}//奇數在加incrementIfOdd = () => {const { value } = this.selectNumberif (this.props.count % 2 !== 0) {this.props.increment(value * 1)}}//異步加incrementAsync = () => {const { value } = this.selectNumberthis.props.incrementAsync(value * 1, 500)}render() {// console.log('UI組件接收到的props是',this.props);return (<div><h2>我是Count組件,下方組件總人數為:{this.props.personCount}</h2><h1>當前求和為:{this.props.count}</h1><select ref={c => this.selectNumber = c} name="" id=""><option value="1">1</option><option value="2">2</option><option value="3">3</option></select>&nbsp;<button onClick={this.increment}>+</button>&nbsp;<button onClick={this.decrement}>-</button>&nbsp;<button onClick={this.incrementIfOdd}>當前求和為奇數再加</button>&nbsp;<button onClick={this.incrementAsync}>異步加</button></div>)}
}// 使用connect()()創建并暴露一個Count的容器組件
// 語法精簡與API精簡
export default connect(// 現在redux管理的是一個對象,所以state是一個對象,需要取出里面的數值state => ({ count: state.count, personCount: state.persons.length }),// mapDispatchToProps的簡寫{increment, //只需要寫到action,就會自動調用dispatchdecrement,incrementAsync}
)(Count)

測試代碼:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script type="text/javascript">// const a = (b) => {//   data: b;// };  //undefined// const a = (b) => {//   return { data: b };// }; //{data: 9}const a = (b) => ({ data: b }); //{data: 9}console.log(a(9));</script></body>
</html>

筆記:

## 1.求和案例 redux 精簡版(1).去除 Count 組件自身的狀態(2).src 下建立:
-redux
-store.js
-count_reducer.js(3).store.js:
1).引入 redux 中的 createStore 函數,創建一個 store
2).createStore 調用時要傳入一個為其服務的 reducer
3).記得暴露 store 對象(4).count_reducer.js:
1).reducer 的本質是一個函數,接收:prestate,action,返回加工后的狀態
2).reducer 有兩個作用:初始化狀態,加工狀態
3).reducer 被第一次調用時,是 store 自動觸發的,傳遞的 prestate 是 undefined,action:@@REDUX/INIT(5).在 index.js 中監測 store 中狀態的改變,一旦發生改變重新渲染<App/>
備注:redux 只負責管理狀態,至于狀態的改變驅動著頁面的展示,要靠我們自己寫。## 2.求和案例 redux 完整版新增文件:
1.count_action.js 專門用于創建 action 對象
2.constant.js 放置容易寫錯的 type 值## 3.求和案例 redux 異步 action 版(1).明確:延遲的動作不想交給組件自身,想交給 action(2).何時需要異步 action:想要對狀態進行操作,但是具體的數據靠異步任務返回。(3).具體編碼:
1).yarn add redux-thunk,并配置在 store 中
2).創建 action 的函數不再返回一般對象,而是一個函數,該函數中寫異步任務。
3),異步任務有結果后,分發一個同步的 action 去真正操作數據。(4).備注:異步 action 不是必須要寫的,完全可以自己等待異步任務的結果了再去分發同步 action。## 4.求和案例 react-redux 基本使用(1).明確兩個概念:
1).UI 組件:不能使用任何 redux 的 api,只負責頁面的呈現、交互等。
2).容器組件:負責和 redux 通信,將結果交給 UI 組件。(2).如何創建一個容器組件————帶 react-redux 的 connect 函數
connect(mapStateToProps,mapDispatchToProps)(UI 組件)
-mapStateToProps:映射狀態,返回值是一個對象-mapDispatchToProps:映射操作狀態的方法,返回值是一個對象(3).備注 1:容器組件中的 store 是靠 props 傳進去的,而不是在容器組件中直接引入(4).備注 2:mapDispatchToProps,也可以是一個對象## 5.求和條例 react-redux 優化(1).容器組件和 UI 組件整合一個文件
(2).無需自己給容器組件傳遞 store,給<App/>包裹一個<Provider store={store}>即可。
(3).使用了 react-redux 后也不用再自己檢測 redux 中狀態的改變了,容器組件可以自動完成這個工作。
(4).mapDispatchToProps 也可以簡單的寫成一個對象
(5).一個組件要和 redux“打交道”要經過哪幾步?
(1).定義好 UI 組件---不暴露
(2).引入 connect 生成一個容器組件,并暴露,寫法如下:connect(
state =>({key:value}), //映射狀態
{key:xxxxxAction} //映射操作狀態的方法
)(UI 組件)
(4).在 UI 組件中通過 this.props.xxxxxxx 讀取和操作狀態## 6.求和案例 react-redux 數據共享版(1).定義一個 Person 組件,和 Count 組件通過 redux 共享數據。
(2).為 Person 組件編號:reducer、action,配置 constant 常量。
(3).重點:Person 的 reducer 和 Count 的 Reducer 要使用 combineReducers 進行分并,合并后的總狀態是一個對象!!!
(4).交給 store 的是總 reducer,最后注意在組件中取出狀態的時候,記得“取到位”。## 7.求和案例 react-redux 開發者工具的使用(1)、yarn add redux-devtools-extension
(2).store 中進行配置
import {composeWithDevTools} from "redux-devtools-extension"
const store = createStore(allReducer,composeWithDevTools(applyMiddleware(thunk)))## 8.求和案例 react-redux最終版
(1).所有變量名字要規范,盡量觸發對象的簡寫形式。(2).reducers文件夾中,編寫index.js專門用于匯總并暴露所有的reducer

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

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

相關文章

GPU集群搭建

1. 硬件規劃與采購 GPU 服務器&#xff1a;挑選契合需求的 GPU 服務器&#xff0c;像 NVIDIA DGX 系列就不錯&#xff0c;它集成了多個高性能 GPU。網絡設備&#xff1a;高速網絡設備不可或缺&#xff0c;例如萬兆以太網交換機或者 InfiniBand 交換機&#xff0c;以此保證節點…

ZYNQ 純PL端邏輯資源程序固化流程

ZYNQ 純PL端邏輯資源程序固化 ZYNQ的程序固化流程比傳統的FPGA固化流程復雜很多&#xff0c;Vivado生成的bit文件無法直接固化在ZYNQ芯片中。因為ZYNQ 非易失性存儲器的引腳&#xff08;如 SD 卡、QSPI Flash&#xff09;是 ZYNQ PS 部分的專用引腳。這些非易失性存儲器由 PS …

[計算機科學#6]:從鎖存器到內存,計算機存儲的構建與原理

【核知坊】&#xff1a;釋放青春想象&#xff0c;碼動全新視野。 我們希望使用精簡的信息傳達知識的骨架&#xff0c;啟發創造者開啟創造之路&#xff01;&#xff01;&#xff01; 內容摘要&#xff1a;在上一篇文章中&#xff0c;我們深入了解了計算機如…

如何刪除Google Chrome中的所有歷史記錄【一鍵清除】

谷歌瀏覽器記錄了用戶訪問過的網站。這方便了查找&#xff0c;但有時也需要清理。刪除所有歷史記錄很簡單&#xff0c;只要按照以下步驟操作。 1. 打開谷歌瀏覽器 首先要啟動谷歌瀏覽器。點擊右上角的三個點&#xff0c;進入主菜單。 2. 進入歷史記錄界面 在菜單中找到“歷史…

關于瀏覽器對于HTML實體編碼,urlencode,Unicode解析

目錄 HTML實體編碼 URL編碼 Unicode編碼 解析層次邏輯 為什么<script></script>不可以編碼符號 為什么不能編碼JavaScript:協議 為什么RCDATA標簽中的都會被解析成文本 為什么HTML編碼了<>無法執行 HTML實體編碼 通過特殊語法&#xff08;<、>…

【數據分享】2020年中國高精度森林覆蓋數據集(免費獲取)

森林作為全球陸地生態系統的主體&#xff0c;分布面積廣、結構復雜&#xff0c;承擔著調節氣候、維護生態安全、改善環境等方面的重要作用。我國的森林資源豐富&#xff0c;據《中國森林資源報告&#xff1a;2014—2018》統計&#xff0c;我國森林覆蓋率已經達到23.04%。森林覆…

C語言學習之動態內存的管理

學完前面的C語言內容后&#xff0c;我們之前給內存開辟空間的方式是這樣的。 int val20; char arr[10]{0}; 我們發現這個方式有兩個弊端&#xff1a;空間是固定的&#xff1b;同時在聲明的時候必須指定數組的長度&#xff0c;一旦確定了大小就不能調整的。 而實際應用的過程中…

【深度學習-Day 2】圖解線性代數:從標量到張量,理解深度學習的數據表示與運算

Langchain系列文章目錄 01-玩轉LangChain&#xff1a;從模型調用到Prompt模板與輸出解析的完整指南 02-玩轉 LangChain Memory 模塊&#xff1a;四種記憶類型詳解及應用場景全覆蓋 03-全面掌握 LangChain&#xff1a;從核心鏈條構建到動態任務分配的實戰指南 04-玩轉 LangChai…

首頁數據展示

排版 現在做首頁的排版&#xff0c;依舊是偷antd里面的東西 使用card包裹list的樣式 import React from react import axios import { Card, Col, Row, List } from antd import { EditOutlined, EllipsisOutlined, SettingOutlined } from ant-design/icons; import { Avat…

使用Set和Map解題思路

前言 Set和Map這兩種數據結構,在解決一些題上&#xff0c;效率很高。跟大家簡單分享一些題以及如何使用Set和Map去解決這些題目。 題目鏈接 136. 只出現一次的數字 - 力扣&#xff08;LeetCode&#xff09; 138. 隨機鏈表的復制 - 力扣&#xff08;LeetCode&#xff09; 舊…

嘗試leaflet+webassemly

前言 筆者在github發現rust版本的leaflet&#xff0c;發現是用wasm-bindgen包裝的&#xff0c;嘗試使用一下 Issues slowtec/leaflet-rshttps://github.com/slowtec/leaflet-rs 正文 準備 新建一個react項目&#xff0c;安裝rsw依賴 pnpm i -D vite-plugin-rsw cargo ins…

機器學習實戰,天貓雙十一銷量與中國人壽保費預測,使用多項式回歸,梯度下降,EDA數據探索,彈性網絡等技術

前言 很多同學學機器學習時總感覺&#xff1a;“公式推導我會&#xff0c;代碼也能看懂&#xff0c;但自己從頭做項目就懵”。 這次我們選了兩個小數據集&#xff0c;降低復雜度&#xff0c;帶大家從頭開始進行分析&#xff0c;建模&#xff0c;預測&#xff0c;可視化等&…

SQL數據庫系統全解析:從入門到實踐

一、數據庫世界入門指南 在數字時代&#xff0c;數據就像新時代的石油&#xff0c;而數據庫系統就是儲存和管理這些寶貴資源的倉庫。對于初學者來說&#xff0c;理解數據庫的基本概念是邁入這個領域的第一步。 數據庫本質上是一個有組織的數據集合&#xff0c;它允許我們高效…

【大模型】圖像生成:StyleGAN3:生成對抗網絡的革命性進化

深度解析StyleGAN3&#xff1a;生成對抗網絡的革命性進化 技術演進與架構創新代際技術對比StyleGAN3架構解析 環境配置與快速入門硬件要求安裝步驟預訓練模型下載 實戰全流程解析1. 圖像生成示例2. 自定義數據集訓練3. 潛在空間操作 核心技術深度解析1. 連續信號建模2. 傅里葉特…

PHP-Cookie

Cookie 是什么&#xff1f; cookie 常用于識別用戶。cookie 是一種服務器留在用戶計算機上的小文件。每當同一臺計算機通過瀏覽器請求頁面時&#xff0c;這臺計算機將會發送 cookie。通過 PHP&#xff0c;您能夠創建并取回 cookie 的值。 設置Cookie 在PHP中&#xff0c;你可…

“Everything“工具 是 Windows 上文件名搜索引擎神奇

01 Everything 和其他搜索引擎有何不同 輕量安裝文件。 干凈簡潔的用戶界面。 快速文件索引。 快速搜索。 快速啟動。 最小資源使用。 輕量數據庫。 實時更新。 官網&#xff1a;https://www.voidtools.com/zh-cn/downloads/ 通過網盤分享的文件&#xff1a;Every…

CSS:選擇器-基本選擇器

文章目錄 1、通配選擇器2、元素選擇器3、類選擇器4、ID選擇器 1、通配選擇器 2、元素選擇器 3、類選擇器 4、ID選擇器

一種動態分配內存錯誤的解決辦法

1、項目背景 一款2年前開發的無線網絡通信軟件在最近的使用過程中出現網絡中傳感器離線的問題&#xff0c;此軟件之前已經使用的幾年了&#xff0c;基本功能還算穩定。這次為什么出了問題。 先派工程師去現場調試一下&#xff0c;初步的結果是網絡信號弱&#xff0c;并且有個別…

React 第三十四節 Router 開發中 useLocation Hook 的用法以及案例詳解

一、useLocation基礎用法 作用&#xff1a;獲取當前路由的 location 對象 返回對象結構&#xff1a; {pathname: "/about", // 當前路徑search: "?namejohn", // 查詢參數&#xff08;URL參數&#xff09;hash: "#contact", …

DeepSeek-Prover-V2-671B最新體驗地址:Prover版僅適合解決專業數學證明問題

DeepSeek-Prover-V2-671B最新體驗地址&#xff1a;Prover版僅適合解決專業數學證明問題 DeepSeek 團隊于 2025 年 4 月 30 日正式在Hugging Face開源了其重量級新作 —— DeepSeek-Prover-V2-671B&#xff0c;這是一款專為解決數學定理證明和形式化推理任務而設計的超大規模語…