1.使用styled-components管理样式
如果在组件文件中引入一个css文件,那么这个css文件会在全局中生效,也就是说会造成该组件的样式被应用到其他组件上,这时候需要使用 styled-components 来帮助我们管理样式
1.1 准备环境
安装
yarn add styled-components
更改
style.css
为style.js
并引入index.js
1
2
3// index.js
- import './style.css';
+ import './style.js';
1.2 使用流程
创建
style.js
,引入styled-components
1
import styled from '../../../node_modules/styled-components';
编写带有样式的组件容器
1
2
3export const [StyleConponentName] = styled.[TagName]`
[Style]: [Value]
`如:
1
2
3export const Nav = styled.div`
width: 960px;
`在组件中调用样式容器
1
import { [StyleConponentName] } from './style.js'
1
<StyleConponentName>Conetne Text Here</StyleConponentName>
1.3 全局样式的使用
styled-components 默认只应用于单个组件的样式,但是通过其提供的 createGlobalStyle
方法可以创建全局样式,我们在此以引入字体样式为例,在字体所在的文件夹中创建一个 iconfont.js
1 | // iconfont-.js |
之后将 iconfont.js
导入到 App.js
中应用于全局:
1 | import React, { Component } from 'react' |
在此要注意的是,全局样式 <GlobalStyle></GlobalStyle>
必须引入到渲染的根节点中,即与组件同级,不能在其内部添加任何组件。
1.4 子级样式的使用
如果创建的样式组件需要通过className来判断样式,则使用 &.className{...}
来编写样式,如:
1 | <!-- jsx --> |
1 | // style.js |
2. 使用combineReducers完成对数据的拆分管理
Reducer主要负责对action的判断和数据的处理以及初始化工作,假如我们把所有组件的操作都放到一个reducer.js
文件中去处理,那么可能就会导致代码过长,所以Redux提供了一个 combineReducers()
API可以让我们把Reducer拆分到每个组件中,再合并到主要的Reducer文件中。
目录结构:
1 | /src |
/comon/header
中存放了header组件的的相关信息,我们可以把与该组件有关的store单独写在该目录下的 store
文件夹中。
2.1 主要步骤
在
/common/header/store/reducer.js
编写关于header
组件的reducer操作1
2
3
4
5
6
7
8const defaultState = {
[dataName]: [value]
// ... ... 处理初始化数据
}
export default (store = defaultState, action) => {
// ... ... 处理action
return store;
}/common/header/store/index.js
作为模块出口导出模块1
2import reducer from './reducer'
export { reducer }改写
/store/reducer.js
,在此引入combineReducers
方法,然后将合并好的reducer导出:1
2
3
4
5
6
7
8import { combineReducers } from 'redux'
import { reducer as HeaderReducer } from '../common/header/store'
const reducer = combineReducers({
header: HeaderReducer
})
export default reducer如果在组件中调用数据,则需要将原来的
state.[dataName]
改为state.[componentName].[dataName]
,如:1
2
3
4
5
6const mapStateToProps = (state) => {
return {
- focused: state.focused
+ focused: state.header.focused
}
}
2.2 处理出口文件
当我们在代码中引入actionCreators.js
和constants.js
来存放action生成器以及管理变量名时,可以使用已有的index.js
统一向外暴露接口。
目录变更:
1 | /common |
1 | /* /common/header/store/index.js */ |
之后如果需要使用相关的action生成器则只需要调用:
1 | - import * actionCreators from './store/actionCreators.js'; |
3. Immutable.js
3.1 简介
Immutable.js是用来限制某一个数据为不可变更数据,它将原有的数据转化为一个immutable对象,之后如果想要获取某个immutable对象的值,则使用get()
方法。它还提供了一个set()
方法,这个方法并没有去修改原有数据的值,而是将原有值与新值结合,返回一个新的对象。
由于在Redux模型中,Reducer不可以更改state中的数据,只是将一个做了变更的数据交付给Store,由Store去变更数据。在之前的方法中,我们使用深拷贝state来防止变更数据,使用Immutable.js就可以简化操作。
注意:immutable对象只能使用immutable提供的API,且immutable对象不能与普通的对象混用,必须要进行转换。
3.2 API
3.2.1 fromJS() set()
利用immutable中的fromJS()
可以将一个js对象转化成为一个immutable对象,利用set()
方法可以处理immutable对象中的数据:
1 | import { constants } from './index' |
3.2.2 get()
使用get()
方法获取一个immutable对象中的数据(此时state中的数据已被转化为一个immutable对象)
1 | const mapStateToProps = (state) => { |
3.2.3 toJS
作用:将一个Immutable数据转换为JS类型的数据。
用法:value.toJS()
3.2.4 List() 和 Map()
作用:用来创建一个新的List/Map对象
用法:
1 | //List |
3.2.5 List.of() 和 Map.of()
作用:创建一个新的包含value的List/Map对象
用法:
1 | List.of<T>(...values: Array<T>): List<T> |
3.2.6 size
作用:获取List/Map的长度
3.3 将Redux中的所有数据都immutable化
安装redux-immutable
yarn add redux-immutable
在项目的主store中引入redux-immutable提供的combineReducers()
方法去取代redux提供的combineReducers()
方法
1 | - import { combineReducers } from 'redux' |
此时就可以在组件中使用 immutable 来规范化数据了
1 | const mapStateToProps = (state) => { |
也可以利用getIn()
方法写为:
1 | - focused: state.get('header').get('focused') |
4. 在开发过程中使用假数据
由Webpack的特性,项目在本地开发时,通过本地服务器可以访问到 /public
文件夹中的数据,也就是说我们可以再额外创建一个 /api
目录在 /public
目录下,在该目录下防止一些 json 文件来用以模拟访问的 json 数据,这样我们就可以通过 axios 直接访问 http://localhost:8080/api/xxx.json
来获取数据。
5. 用ref获取DOM元素
当我们要获取jsx中的某个DOM元素时,可以使用ref来获取,然后将ref对象作为参数传入方法中,我们就可以在方法中处理该DOM了,例如我们再点击“换一批”时,需要获取icon字体,改变其样式
1 | <SearchInfoSwitch |