建设一个网站需要什么技术,扬中炒地皮,doku做网站,设计说明500字通用一、安装和配置
React 官方并没有提供对应的状态机插件#xff0c;因此#xff0c;我们需要下载第三方的状态机插件 —— Redux。
1、下载Redux
在终端中定位到项目根目录#xff0c;然后执行以下命令下载 Redux
npm i redux
2、创建配置文件
在 React 中#xff0c;…一、安装和配置
React 官方并没有提供对应的状态机插件因此我们需要下载第三方的状态机插件 —— Redux。
1、下载Redux
在终端中定位到项目根目录然后执行以下命令下载 Redux
npm i redux
2、创建配置文件
在 React 中不会自动生成状态机的相关配置代码因此需要我们自己手动去创建目录以及配置文件。
我们可以在 src 的目录中创建一个 redux 或 store 的目录用来存放所有关于状态机的配置文件。然后在该目录中创建一个 store.js 文件作为整个状态机的入口文件。
3、配置状态机
3.1、创建store仓库对象
import {legacy_createStore as createStore} from redux
const storecreateStore();
3.2、保存数据到store中
createStore 方法接收一个函数作为参数该函数的返回值会保存到 store 仓库中
const store createStore((state 数据初始值) {return state;
});
通过函数参数的默认值的方式来设置仓库数据的初始值
3.3、查看仓库数据
在 store 仓库对象身上提供了一个 getState() 方法用来查看仓库中的所有数据
console.log(store.getState());
由于目前没有任何文件中在引入状态机的配置文件如果我们需要查看仓库中的数据暂时需要在 index.js 中引入 /redux/store.js 文件来让其运行。
二、Redux核心概念
1、Redux工作流程 2、Redux组成部分
2.1、state
state:状态就是我们传递的数据
2.2、action
action是一个通知对象里面必须有一个type属性表示当前通知的类型至于其他属性你可以任意添加
可以通过store.dispatch(action对象)来更新仓库中的数据
注意 在实际开发中更多人喜欢用action创建函数 在实际开发中大多数情况下type会被定义成字符串常量
2.3、reducer
reducer本质是一个函数它用来响应发送过来的actions,经过处理把state发送给store 在reducer函数中需要return返回值这样store才能接收到数据 reducer函数接收两个参数第一个参数是初始化store,第二个参数是action 2.4、store
数据仓库存放组件数据的地方。一个项目一般只有一个数据仓库,store可以把action和reducer联系在一起。
主要的职责 维护应用的state 提供getState()方法获取state 提供dispatch()方法发送action 通过subscribe()来注册监听 通过subscribe()返回值来注销监听
三、第一个Redux程序
1、创建action 在src目录下创建一个actions文件夹 在该目录下创建一个index.js文件 action是一个通知对象里面必须有一个type属性这里的num属性是自定义的表示计数器每次增加的个数
const incrementAction{type:increment,num:1
}
export {incrementAction}
2、创建reducer 在src目录下创建reducers目录 在该目录下创建index.js文件用来构建reducer注意reducer要接收两个参数 第一个参数是默认状态我们可以定义一个初始化的state然后进行赋值 在函数里面判断第二个参数action的type值是否是我们发送过的,如果是我们可以通过return返回新的state
const counterReducer(state0,action){switch(action.type){case increment:return stateaction.numdefault:return state}
}
export {counterReducer}
3、创建store 在src目录下创建一个文件夹store 在该目录下创建index.js文件用来构建store,注意createStore函数第一个参数接收的是reducer
import {legacy_createStore as createStore} from redux
import {counterReducer} from ../reducers
const storecreateStore(counterReducer)
export default store
4、在组件中使用 创建components文件夹该目录下存放自定义组件 在该目录下新建Counter.jsx文件 将Counter.jsx引入到App.js文件中
import Counter from ./components/Counter;
function App() {return (divCounter/Counter/div);
}
export default App; 调用dispatch函数,更新仓库的数据
import React,{useEffect,useState} from react
import store from ../redux/store
import {incrementAction} from ../redux/actionsexport default function Counter() {const increment(){store.dispatch(incrementAction)}return (divh1计数器:{store.getState()}/h1button onClick{(){increment()}}/button/div)
} 当组件加载完毕后调用 store. subscribe注册监听监听state数据的变化
import React,{useEffect,useState} from react
import store from ../redux/store
import {incrementAction} from ../redux/actionsexport default function Counter() {const [count, setCount] useState(0);const increment(){store.dispatch(incrementAction)}useEffect((){store.subscribe((){console.log(正在监控store.getState());setCount({})})})return (divh1计数器:{store.getState()}/h1button onClick{(){increment()}}/button/div)
}
四、redux中action和reducer的优化
1、action优化
1.1、action creator
我们一般会在页面里面修改数据即在页面里面调用store的dispatch方法。那就意味着action对象中的num字段很大可能是动态的即不同的页面num字段可能是不同的这样我们就不能把action写成一个死的对象最好是封装成一个函数执行过后返回一个action通知对象然后num的值通过函数的参数来决定。这样的函数我们称之为action创建函数action creator
const incrementAction(num){return{type:increment,num:num}
}
export {incrementAction}
1.2、type常量
在实际开发中type在多数情况下会被定义成常量如下所示 在src/actions目录下新建actionTypes.jsx文件将所有type类型定义成常量
export const INCREMENT increment 在action creator中引入
import {INCREMENT} from ./constant
const incrementAction(num){return{type:INCREMENT,num:num}
}
export {incrementAction}
2、reducer优化
项目中肯定不止一个数据所以state的默认值应该是一个对象而不是其他。而且除了默认值每当case到一个条件返回一个新的对象时应该返回一个全新的对象然后才是你要修改的数据当然这些数据如果是引用类型的话应该修改其引用本身否则界面可能不会更新尽管数据发生变化了
import { INCREMENT } from ../actions/constant
const counterReducer (state { num: 0 }, action) {switch (action.type) {case INCREMENT:return {...state,num: state.num action.num}default:return state}
}
export { counterReducer }
优化后在组件中调用的代码如下
import React,{useEffect,useState} from react
import store from ../redux/store
import {incrementAction} from ../redux/actionsexport default function Counter() {const [count, setCount] useState(0);const increment(){store.dispatch(incrementAction(2))}useEffect((){store.subscribe((){console.log(正在监控store.getState());setCount({})})})return (divh1计数器:{store.getState()}/h1button onClick{(){increment()}}/button/div)
}
五、react-redux概述
为了方便使用Redux 的作者封装了一个 React 专用的库 React-Redux本文主要介绍它。
React-Redux 将所有组件分成两大类UI 组件presentational component和容器组件container component。
1、UI组件
UI 组件有以下几个特征。 只负责 UI 的呈现不带有任何业务逻辑 没有状态即不使用this.state这个变量 所有数据都由参数this.props提供 不使用任何 Redux 的 API
2、容器组件
容器组件有以下几个特征。 负责管理数据和业务逻辑不负责 UI 的呈现 带有内部状态 使用 Redux 的 API
总之只要记住一句话就可以了UI 组件负责 UI 的呈现容器组件负责管理数据和逻辑。
React-Redux 规定所有的 UI 组件都由用户提供容器组件则是由 React-Redux 自动生成。也就是说用户负责视觉层状态管理则是全部交给它。
六、react-redux基本使用
1、安装react-redux
npm i react-redux
npm i redux
2、创建action 在constant.jsx中添加INCREMENT
export const INCREMENTincrement; 在src/actions/index.jsx中添加incrementAction
import { INCREMENT } from ./constant;
export const incrementActionnum({type:INCREMENT,num})
3、创建reducer 在src/reducers/index.jsx中添加counterReducer
import {INCREMENT} from ../actions/constant
const counterReducer(state{num:0},action){switch(action.type){case INCREMENT:return{...state,num:state.numaction.num}default:return state}
}
export {counterReducer}
4、创建store
在src/store/index.jsx中编写代码如下
import {legacy_createStore as createStore} from redux
import {counterReducer} from ../reducers
const storecreateStore(counterReducer)
export default store
5、全局注入store仓库 在index.js中导入Provider组件
import {Provider} from react-redux 利用provider组件将整个接口进行包裹 给Provider组件设置store的属性该属性的值就是通过createStore构建出来的store实例对象
import ReactDOM from react-dom/client
import App from ./App;
import {Provider} from react-redux
import store from ./store
const root ReactDOM.createRoot(document.getElementById(root));
root.render(Provider store{store}App //Provider
); Provider在根组件外面包了一层这样一来App的所有子组件就默认都可以拿到state了。
6、组件关联仓库
由于UI组件不能使用Redux的API所以如果在组件中如果要使用Redux就必须将UI组件变成容器类组件
React-Redux 提供connect方法用于从 UI 组件生成容器组件。connect的意思就是将这两种组件连起来
import React from react
import { connect } from react-reduxfunction Counter() {render() {return (div/div)}
}
export default connect()(Counter)
7、组件操作仓库
7.1、获取仓库数据
connect 方法接收一个回调函数作为参数
const mapStateToProps () {}
export default connect(mapStateToProps)(Counter);
该回调函数本身又可以通过第一个参数接收到仓库中的所有数据
const mapStateToProps (state) {console.log(state); // 仓库中所有的数据
}
export default connect(mapStateToProps)(Counter);
在该回调函数中返回一个对象该对象会和组件的 props 进行合并。换句话说该函数的返回值会添加到组件的 props 中
const mapStateToProps (state) {return {数据名: 从 state 中获取的数据值}
}
export default connect(mapStateToProps)(Counter);
处理完成后我们就可以在组件的 props 中访问到对应的仓库数据了
function Counter(props)render() {return (divh1计数器/h1h2{props.数据名}/h2/div)}
}
7.2、修改仓库数据
修改仓库数据依然是通过 dispatch() 方法来触发修改操作。
在组件中只要和仓库关联过就能在 props 上直接获取到 dispatch 方法。因此在组件中可以直接通过 props.dispatch() 方法来触发修改数据的操作。
import React,{useEffect,useState} from react
import store from ../redux/store
import {incrementAction} from ../redux/actions
import { connect } from react-redux;function Counter(props) {const increment(){props.dispatch(incrementAction(3))}return (divh1计数器:{props.num}/h1button onClick{(){increment()}}/button/div)
}
const mapStateToProps (state) {console.log(state); // 仓库中所有的数据return{num:state.num}
}
export default connect(mapStateToProps)(Counter)
七、状态机的Hook
针对 React 中的函数组件React-Redux 中也提供了第三方的 Hook。
1、useSelector
通过调用 useSelector 方法并传递一个回调函数作为参数我们可以在这个回调函数中获取到仓库中的 state。
import { useSelector } from react-redux
useSelector((state) {console.log(state); // 仓库中所有的数据
})
然后我们可以在回调函数中将我们需要使用的数据 return 出来然后用一个变量来接收
const data useSelector((state) {return 数据;
})
后续组件要使用数据就可以直接通过变量进行数据的访问了。
2、useDispatch
调用 useDispatch() 方法可以直接获取到 dispatch() 方法。
import { useDispatch } from react-redux
export default fucntion Test() {const dispatch useDispatch();return ()
}
如果组件中使用 Hook 来获取 dispatch 方法的话就不再需要使用 connect 来对组件和仓库进行关联了。
获取到 dispatch 方法后后续的使用就和 props.dispatch 的使用一致。
关键代码
import React from react
import {useDispatch,useSelector} from react-redux
import {incrementAction} from ../../redux/actionexport default function Counter(props) {const numuseSelector((state){return state.num})const dispatchuseDispatch()const increment(){dispatch(incrementAction(3))}return (divh1计数器:{num}/h1button onClick{(){increment()}}/button/div)
}
八、reducer拆分
当项目越来越大的时候需要管理的数据也会越来越多如果所有的数据都由一个reducer管理的话则这个reducer肯定会变得非常的臃肿且难以维护。所以有必要对reducer做一个拆分不同功能模块的数据切片由不同的reducer来管理。假设现在有两个模块账户管理模块和商品管理模块每个模块都有数据需要管理
import {combineReducers} from redux
import counterReducer from ./counterReducer
export default combineReducers({counter:counterReducer
})
注意调用时候需要使用使用到切片的名字才能访问到比如
import React from react
import {useSelector} from react-redux
export default function Counter(props) {const countuseSelector((state){console.log(state);return state.counter.num //state.切片名的key.num})return (divh1计数器:{count}/h1/div)
}