作为前端,还是什么都知道一些的好,国人还是用 Vue 生态较多。

优雅的 css module

react 不像 vue 有 scoped
create-react-app 默认集成了 css-module
个人感觉也是比较好使的一种方式

  1. 命名需要已 .module 的方式结尾并在组件中引入 styles 对象

———————– 手动间隙 ———————–

  1. 在 jsx 中定义 className

———————– 手动间隙 ———————–

  1. 在 css 文件中定义样式,要覆盖其他组件的样式则用 :global

———————– 手动间隙 ———————–

  1. 覆盖其他组件的样式生成后

———————– 手动间隙 ———————–

  1. 后代选择器类名生成后

———————– 手动间隙 ———————–

  1. 传入组件的 props 中涉及类名的,也需要使用 styles 对象的方式

———————– 手动间隙 ———————–

注意

建议采用后代选择器的方式定义类名,而非短横线
jsx 中会方便很多(对象写法以及 ide 代码提示)

<div className={ styles.banner }>
  {/** 不方便 **/}
  <div className={ styles['banner-pic'] }></div>
  
  {/** 方便 **/}
  <div className={ styles.pic }></div>
</div>

———————– END ———————–

事件传参以及 this 指向

  • render 中写成函数封函数的方式,传递 event 对象和其他参数
  • 如果事件处理函数中需要 this,需要写成下面这种形式,否则 this 指向错误(public class fields 语法)

———————– END ———————–

react-router 到底引入哪一个

只引入 react-router-dom 即可

  • react-router(实现路由的核心)
  • react-router-dom(在 react-router 的基础上多了一些组件)

———————– END ———————–

react-router 传参

  • 显式 - path 传参

    用处:参数数量少的情况下
    优点:刷新页面参数仍然存在,可清楚表达语义
    缺点:path 参数位置固定,参数过多可能导致灵活问题


  • 显式 - 查询字符串传参

    用处:参数数量多的情况下
    优点:刷新页面参数仍然存在
    缺点:不如 path 传参语义性强


  • 隐式 - state 传参

    用处:参数保密 / 参数数量多的情况
    优点:对象传参,写起来简单,保证参数安全性
    缺点:页面刷新后参数失效

———————– END ———————–

react-router js 跳转

组件中

在页面级组件上,默认已有 props.history
在非页面级组件中,使用 withRouter 封装后会给 props 设置 history 属性

———————– 手动间隔 ———————–

非组件中

在其他 js 中,可以使用 history 库来实现
react-router 有依赖不用自己安装,直接引入即可

———————– END ———————–

react-router 路由嵌套

  • 主路由

  • 子路由

react-redux 使用步骤

我个人不太喜欢在用常量表示 type
需要多一层定义引用…着实麻烦
个人喜欢通过 mapStateToProps 和 mapDispatchToProps 引入全部的 state 和 actions
这样的缺点是会混淆组件内部的状态和方法来源,但是可以通过加前缀的形式区分
比如: state: { storeValue }, actions: { setStoreValue }

  1. 引入
    npm i --save redux
    npm i --save react-redux
    

———————– 手动间隔 ———————–

  1. 创建 /store/reducer.js 文件
    ```javascript
    const defaultState = {
    storeValue: null
    }

export default function (state = defaultState, action) {
switch (action.type) {
case ‘storeValue’: {
return { …state, value: action.value }
}
default: {
return state
}
}
}

----------------------- 手动间隔 -----------------------

3. 创建 /store/actions.js 文件
```javascript
export const setStoreValue = function (value) {
  return {
    type: 'storeValue',
    value
  }
}

———————– 手动间隔 ———————–

  1. 创建 /store/index.js 文件
    ```jsx harmony
    import { createStore } from ‘redux’
    import reducer from ‘./reducer’
    import * as actions from ‘./actions’

let store = createStore(reducer)

/** 默认引用全部的 state 和 actions **/
let mapStateToProps = function (state) {
return {
…state
}
}
let mapDispatchToProps = function (dispatch) {
return actions
}

export default store

export {
store,
mapStateToProps,
mapDispatchToProps
}

----------------------- 手动间隔 -----------------------

5. 将 Provider 包裹在 App 组件的外侧,同时传入 /store/index.js 暴露的 store 作为 prop
```jsx harmony
import React from 'react'
import ReactDOM from 'react-dom'

import { Provider } from 'react-redux'
import store from './store'

import App from './App'

ReactDOM.render(
  <Provider store={ store }>
    <App/>
  </Provider>,
  document.getElementById('root')
)

———————– 手动间隔 ———————–

  1. 在组件中使用 connect 方法连接 redux(通过 props 的方式传入组件)

    this.props.storeValue
    this.props.setStoreValue

    ```jsx harmony
    import { connect } from ‘react-redux’
    import { mapStateToProps, mapDispatchToProps } from ‘../../store’

function Page () {
/** .. **/
}

export default connect(
mapStateToProps,
mapDispatchToProps
)(Page)

```

———————– END ———————–

定义环境变量

  • 创建环境变量文件

  • 自定义的环境变量要以 “REACT_APP_” 作为开头