美文网首页JavaScript学习笔记
当下对React.js的再思考

当下对React.js的再思考

作者: 钢笔先生 | 来源:发表于2019-11-27 23:25 被阅读0次

Time: 2019-11-27

之前在比赛中写前端工程时,使用了如下几个关键的技术点:

  • redux,负责应用状态管理
  • reux-thunk,负责中间件管理
  • 容器组件
  • 展示组件
  • reducer
  • action

首先从redux讲起。

redux的设计原则是用单个字典来存储应用的状态树store,通过action来传递修改状态的信息包,具体的修改是通过定义的reducers函数来执行。

也即我们需要将actions --> reducers --> store三者串联起来。

这三者是为了搭建起来一个自动响应的框架,搭建完是不动的,需要外界dispatch某个action来触发,相当于现在定义了一个状态机,外界的输入进来才会触发响应。

store会在应用的index.js中绑定到全局。

import { store } from './_store'

const rootElement = document.getElementById("root")

console.log("store状态:", store.getState()) // 可以拿到状态

// store已经绑定到了整个App
ReactDOM.render(
    <Provider store={store}>
        <App />
    </Provider>, rootElement
)

一般我们会定义一个store.js用于表示状态,我们会

关于组件,我们抽象为两层组件:

  • 容器组件
  • 展示组件

容器组件负责将状态和要触发的动作绑定到展示组件,展示组件只需要关注自己如何通过HTML + CSS元素表达想要展示的内容,容器组件会把要用到的数据和要dispatch的动作注入到展示组件的props

举个例子:

import { Blacklist } from '../../_pages/company'
import { connect } from 'react-redux'
import { listBlacklistAsync } from '../../_actions/company.actions'

// 容器负责注入状态显示和行为定义,作为显示组件的props

// store状态映射到组件
// store已经在index.js中绑定到应用,这里直接取用即可
// blacklist是用于props的键
const mapStateToProps = state => ({
    blacklist: state.company.blacklist,
    fetchStatus: state.company.fetchStatus,
})

// 注入到展示组件的props中的回调方法
const mapDispatchToProps = dispatch => ({
    listBlacklistAsync: () => dispatch(listBlacklistAsync())
})

// 连接到展示组件
export default connect(
    mapStateToProps,
    mapDispatchToProps
)(Blacklist)

容器组件和展示组件通过connect方法绑定到一起。背后store状态机已经搭建好了。

展示组件调用容器组件准备好的属性和方法:

componentDidMount() {
        this.props.listBlacklistAsync() // 先分发查询修改状态树
    }


render() {
        // this.createData(`0xc83b2cf766d3165acc2fc9164641380088defd1b`, "xx于xx年xx月xx日未还款金额xx元"),
        let rows = []
        // 需要根据状态判定是否已经结束获取
        console.log("组件内显示黑名单:", this.props.blacklist)

        if (this.props.blacklist !== undefined) {
            // this.props.blacklist.map((item, i) => {
            //     rows.push(this.createData(item.weid, item.record))
            // })
            rows = this.props.blacklist
        }

        const { classes } = this.props

        if (this.props.fetchStatus === FETCH_STATUS.FETCH_BEGIN) {
            return (
                <div align="center">
                    <br />
                    <CircularProgress />
                </div>
            )
        }
....

关于action的定义:

程序需要调用的外部数据,我们用fetch获取,获取到的数据可以用到action定义中,外部数据的获取是为了修改组件的状态,而组件的状态现在是由store接管。

看一个action定义的例子:


// dispatch action
const listLoanRequestRecords = (json) => {
    return {
        type: types.LOAN_REQUEST_RECORDS,
        payload: json.data
    }
}


// 定义行为,行为会在容器组件中设定给props,具体显示组件中择时触发
const listLoanRequestRecordsAsync = () => {
    return dispatch => {
        dispatch(fetchBegin())
        // 通过服务拿到数据,最后作为action的payload,action的payload用于修改store,修改行为由reducer执行
        companyServices.listLoanRequestRecords("WeBank").then(
            json => {
                if (json.status === 200) {
                    dispatch(fetchSuccess())
                }
                dispatch(listLoanRequestRecords(json))
            }
        )
    }
}

action是在reducers中使用。所以我们看下reducers的定义:

// 获取用户请求列表
export function loanRequestRecordsReducer(state = [], action) {
    switch (action.type) {
        case types.LOAN_REQUEST_RECORDS:
            return [
                ...state,
                ...action.payload
            ]
        default:
            return state
    }
}

reducer是纯函数,接收当前状态的值然后根据action带来的动作类型和数据包修改store。

不要看参数state=[]就认为store是空,这是默认参数,拿到的是当前的数据。

另外,reducer指定的键名就是store字典树的键名。

比如在store中:

// 会根据定义的键值生成对应的以第一层键指定的store
const rootReducer = combineReducers({
    company: companyReducer,
    government: governmentReducer,
    user: userReducer,
    common: commonReducer
})

一级键就是这四个值:company, government, user, common

这个之前写过一个笔记:
在combineReducers用的是对象,按照key来标记对应的是哪个reducer,键是state的属性名!

这太重要了,我太喜欢这个了,解决了我的困惑。

下一个困惑是,state给空,每次调用都是在干嘛?

是根据分离的reducer对应的属性直接抽出来一段数据过来当参数吗?

如果修改的话就在容器组件中dispatch修改方法

如果只是读取,就在容器组件中getState传到值属性里。

Q: fetch返回的Promise如何触发状态更新?

A: fetch(url).then(response => response.json()).then(json => console.log(json))

这样就串起来应用状态和数据读取的全貌了。

有点乱,后续有时间再梳理。

相关文章

  • 当下对React.js的再思考

    Time: 2019-11-27 之前在比赛中写前端工程时,使用了如下几个关键的技术点: redux,负责应用状态...

  • React 入坑杂谈——写给萌新

    听说,React.js 很火很流行,出于对新鲜事物的好奇,或是新项目的需求,你决定对 React.js 一探究竟。...

  • 对演讲的再思考

    你好,欢迎你的到来。我是凤超,你身边的高效人生教练,学好时间管理和精力管理,过超然人生! 在2018年底,在参加精...

  • 对写作的再思考

    自己参与日更挑战以来,在《简书》写的文章已经突破10万字,这是每天坚持写作日更文章积累的结果,自己至今已经日更...

  • 对思考过程的再思考

    对思考过程的再思考,就是我们常说的批判性思维 ,他的研究对象就是思考,思考我们的思维思维有漏洞或者不完备的地方。 ...

  • 对当下生活的思考

    每个人在不同的时期都会有不同的目标和追求,当上一个目标实现的时候,应该尽快找到下一个目标然后朝着目标努力,但...

  • 对活在当下的思考

    活在当下 我们会经常看到一些文章着重强调,活在当下。反复强调要活在当下,仔细想想言下之意就是说没有活在当下咯。有哲...

  • 写给自己的话--我相信

    ① 每天进步一点点,坚持带来大改变。 ② 先做,再思考,再做,再思考,重复。 ③ 我相信。 ④ 当下,永远是最好最...

  • 再对活在当下的解读

    活在当下 不是花天酒地沉迷游戏不辨西东 不是吃喝玩乐坐吃山空 不是应对理想傻傻坐等 而是凭借着身体奔向自己已描绘出...

  • 寻找真正的自我

    感知到自己的头脑中总是再对投射的人事物做评判,对当下的行动便失去了思考意识。让我的大脑处于发紧的状态,处于无效思维...

网友评论

    本文标题:当下对React.js的再思考

    本文链接:https://www.haomeiwen.com/subject/bexvwctx.html