# react例子 **Repository Path**: huatree/react-examples ## Basic Information - **Project Name**: react例子 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2021-04-11 - **Last Updated**: 2022-05-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # react-examples > wyh | 2021-04-11 **说明:** 通过重命名替换为`src`即可使用对应的项目案例,因为封装的 webpack 默认配置机制。以下例子都是基于create-react-app脚手架编写的。 ## 00 src creat-react-app 创建的原始文件 ## 01 纯 react 版 ## 02 redux 精简版 1. 去除 Count 组件自身的状态 2. src 下建立: ```js - 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 是:{type:'@@REDUX/INIT_a.2.b.4} 5. 在 index.js 中监测 store 中状态的改变,一旦发生改变重新渲染`` 备注:redux 只负责管理状态,至于状态的改变驱动着页面的展示,要靠我们自己写。 ## 03 redux 完整版 新增文件: 1.countAction.js 专门用于创建 action 对象 2.constant.js 放置容易写错的 type 值 ## 04 redux 异步 acton 版 1. 明确:延迟的动作不想交给组件自身,想交给 action 2. 何时需要异步 action:想要对状态进行操作,但是具体的数据靠异步任务返回。 3. 具体编码: - 1).yarn add redux-thunk,并配置在 store 中 - 2).创建 action 的函数不再返回一般对象,而是一个函数,该函数中写异步任务。 - 3).异步任务有结果后,分发一个同步的 action 去真正操作数据。 4. 备注:异步 action 不是必须要写的,完全可以自己等待异步任务的结果了再去分发同步 action。 ## 05 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,也可以是一个对象 ## 06 react-redux 优化版 1. 容器组件和 UI 组件整合一个文件 2. 无需自己给容器组件传递 store,给``包裹一个``即可。 3. 使用了 react-redux 后也不用再自己检测 redux 中状态的改变了,容器组件可以自动完成这个工作。 4. mapDispatchToProps 也可以简单的写成一个对象 5. 一个组件要和 redux“打交道”要经过哪几步? - 1).定义好 UI 组件---不暴露 - 2).引入 connect 生成一个容器组件,并暴露,写法如下: ```jsx connect( state => ({key:value}), //映射状态 {key:xxxxxAction} //映射操作状态的方法 )(UI 组件) ``` - 3).在UI组件中通过this.props.xxxxxxx读取和操作状态 ## 07 react-redux 数据共享版 1. 定义一个 Pserson 组件,和 Count 组件通过 redux 共享数据。 2. 为 Person 组件编写:reducer、action,配置 constant 常量。 3. 重点:Person 的 reducer 和 Count 的 Reducer 要使用 combineReducers 进行合并, 合并后的总状态是一个对象!!! 4. 交给 store 的是总 reducer,最后注意在组件中取出状态的时候,记得“取到位”。 ## 08 react-redux 开发者工具的使用 1. yarn add redux-devtools-extension 2. store 中进行配置 ```js import {composeWithDevTools} from 'redux-devtools-extension' const store = createStore(allReducer,composeWithDevTools(applyMiddleware(thunk))) ``` ## 09 react-redux 最终版 1. 所有变量名字要规范,尽量触发对象的简写形式。 2. reducers 文件夹中,编写 index.js 专门用于汇总并暴露所有的 reducer **注意**:打包测试的话,以可用 serve 运行打包后的文件 ```bash yarn add serve -g # create-react-app脚手架创建的项目,打包的目录默认为build yarn serve ./build ``` ## 10 route原理 > 2021-04-15 ## 11 react-router-dom的基本使用 > 2021-04-15 react-route官方给出了三种:web、native、any。react-router-dom即为web类型。 > 2021-04-17 - 路由组件与一般组件 1. 写法不同: 一般组件:`` 路由组件:`` 2. 存放位置不同: 一般组件:components 路由组件:pages 3. 接收到的props不同: 一般组件:写组件标签时传递了什么,就能收到什么 路由组件:接收到三个固定的属性 ```js history: go: ƒ go(n) goBack: ƒ goBack() goForward: ƒ goForward() push: ƒ push(path, state) replace: ƒ replace(path, state) location: pathname: "/about" search: "" state: undefined match: params: {} path: "/about" url: "/about" ``` ## 12 NavLink的使用 > 2021-04-17 NavLink可以实现路由链接的高亮,通过activeClassName指定样式名 ## 13 封装NavLink > 2021-04-17 注意:`props.children`的简写方式 ## 14 Switch的使用 > 2021-04-17 1. 通常情况下,path和component是一一对应的关系。 2. Switch可以提高路由匹配效率(单一匹配)。 ## 15 模糊匹配与精准匹配 > 2021-04-17 1. 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致) 2. 开启严格匹配:`` 3. 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由 ## 16 Redirect重定向 > 2021-04-17 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由 ## 17 嵌套路由 > 2021-04-17 1. 注册子路由时要写上父路由的path值 2. 路由的匹配是按照注册路由的顺序进行的 ## 18-20 路由组件传参 > 2021-04-17 1. params参数(地址栏带参) 路由链接(携带参数):`详情` 注册路由(声明接收):`` 接收参数:props.match.params 2. search参数(地址栏带参) 路由链接(携带参数):`详情` 注册路由(无需声明,正常注册即可):`` 接收参数:this.props.location.search 备注:获取到的search是urlencoded编码字符串,需要借助querystring解析 3. state参数(地址栏无参) 路由链接(携带参数):`详情` 注册路由(无需声明,正常注册即可):`` 接收参数:this.props.location.state 备注:虽然地址栏没显示参数,但是刷新也可以保留住参数 ## 21-23 编程式路由导航及withRouter > 2021-04-17 借助this.prosp.history对象上的API对操作路由跳转、前进、后退 - this.prosp.history.push() - this.prosp.history.replace() - this.prosp.history.goBack() - this.prosp.history.goForward() - this.prosp.history.go() ## 24 BrowserRouter与HashRouter的区别 > 2021-04-17 1. 底层原理不一样: BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。 HashRouter使用的是URL的哈希值。 2. path表现形式不一样 BrowserRouter的路径中没有#,例如:localhost:3000/demo/test HashRouter的路径包含#,例如:localhost:3000/#/demo/test 3. 刷新后对路由state参数的影响 BrowserRouter没有任何影响,因为state保存在history对象中。 HashRouter刷新后会导致路由state参数的丢失!!! 4. 备注:HashRouter可以用于解决一些路径错误相关的问题。如public的css样式丢失。 ## 25 路由菜单遍历选中高亮及刷新不变 > 2021-04-18 **需求:** 1. 自定义菜单布局 2. 第一层菜单无路由配置,第二层菜单有路由 3. 选中第一层菜单,及第二层菜单高亮显示 4. 刷新页面,选中的显示状态不变 5. 前进、后退第一层菜单与第二层保持一致状态