以Sia-UI项目的文件组件为例参考阮一峰老师的react-redux入门教程对react-redux的用法总结

过一段时间后的批注:看了慕课网老师的react课程,这篇文章我推荐的链接还是值得看,但我对react的解释就不用看啦,因为部分理解还是不到位,而且没有对中间件的解释,但我是不会删除这个宝藏的,嘻嘻。

阮一峰老师的文章链接:http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
Sia-UI的github链接:https://github.com/NebulousLabs/Sia-UI
博客写完也差不多记住了,记住步骤了就理解了,没记住就看不懂,这是我对react-redux的深刻理解,哈哈。

有几个关键名词需要记一下,定义是我理解的写法⊙_⊙
ui组件:只负责美,页面的展示;这部分就是展示数据而已而已啦。
容器组件:只负责脑子,页面的逻辑,如果二者有重合的话,要井水不犯河水,细分细分细分成更小的ui组件和容器组件。这部分就是对数据进行处理,调起action里的事件。
action:组件里所有事件的定义都写在这里,具体就是ui组件里面要调用的事件名字,为什么这样,因为代码就要规规矩矩,整整齐齐,这样才能透出满屏的大佬范;这部分就是让你往东,你不能往西的作用。
reducer:根据用户触发的action具体事件在自己内部找到具体处理方法,更新一些状态的值,再把这些值传给容器组件;这部分就是让你往东,东到具体哪个位置,乱东要挨打的哟。

总体思路就是这样的:
1.先在ui组件里面绑定事件,等待触发
2.用户触发后,关键点,容器组件将触发的事件名匹配mapDispatchToProps这个参数定义的相应事件,触发action
3.action收到通知后,找到事件对应的type类型
4.然后由reducer判断对应的type类型,设置对应的状态值
5.然后由容器组件的mapStateToProps参数更新到对应的view上面
反正我是这么理解的◑﹏◐◑﹏◐◑﹏◐,如果理解错了,下边的文字也是可以看一看的。

一、附一张项目代码结构图

以Sia-UI项目的文件组件为例参考阮一峰老师的react-redux入门教程对react-redux的用法总结_第1张图片

二、file组件目录结构解释

assets/放各种image文件
css/放各种css文件
index.html      --    1.react-root:定义根节点
                             line15--用法:





	Files
	
	
	
	
	



	
	

划重点----------------------------------------------------------------------------------------

js/index.js     --     1.createStore from redux:创建store对象,store对象用来保存状态数据
                            line17--用法:const store = createStore(rootReducer, applyMiddleware(sagaMiddleware))
                            store.getState('xx');store.dispatch('loadData')。手动获取状态,触发事件,很方便。
                         (1)rootReducer:用户触发一个action,store对象需要对相应的数据进行state更新,然后反映到view组件,这种state的变化是通过reducer处理的。
                         (2)sagaMiddleware为中间件这个处理异步请求的,没有异步请求就不用,这个不懂,省略。
                            2.Provider from react-redux:给容器组件传递state对象,包在最外层,这样App组件内的所有组件都能拿到state对象
                            line21--用法:
                            3.ReactDOM form react-dom:在根节点渲染react组件
                            line25--用法:ReactDOM.render(rootElement, document.getElementById('react-root'))

import React from 'react'
import ReactDOM from 'react-dom'
import createSagaMiddleware from 'redux-saga'
import { createStore, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import rootReducer from './reducers/index.js'
import rootSaga from './sagas/index.js'
import App from './containers/app.js'
import { fetchData } from './actions/files.js'

// If dev enable window reload
if (process.env.NODE_ENV === 'development') {
  require('electron-css-reload')()
}

const sagaMiddleware = createSagaMiddleware()
const store = createStore(rootReducer, applyMiddleware(sagaMiddleware))
sagaMiddleware.run(rootSaga)

const rootElement = (
  
    
  
)
ReactDOM.render(rootElement, document.getElementById('react-root'))

// update state when plugin is focused
window.onfocus = () => {
  store.dispatch(fetchData())
}

状态管理解释----------------------------------------------------------------------------------------

js/reducers/index.js     --     1.combineReducers from redux:将多个状态处理合并为一个大的,对于大项目需要各司其职,不然很容易乱
                                            line8-用法:const rootReducer = combineReducers({wallet,files,deletedialog,renamedialog,allowancedialog})

import { combineReducers } from 'redux'
import wallet from './wallet.js'
import files from './files.js'
import deletedialog from './deletedialog.js'
import renamedialog from './renamedialog.js'
import allowancedialog from './allowancedialog.js'

const rootReducer = combineReducers({
  wallet,
  files,
  deletedialog,
  renamedialog,
  allowancedialog
})

export default rootReducer

js/reducers/allowancedialog.js     --    以allowancedialog为例解释具体到某一个reducer的用法
                                                            reducer接收state和action两个参数,state为默认的状态键值对,reducer根据action触发的事件类型设置相应的state状态;action由ui组件中相应的事件触发

import { Map } from 'immutable'
import * as constants from '../constants/files.js'

const initialState = Map({
  storageEstimate: '0 B',
  feeEstimate: 0,
  confirming: false,
  confirmationAllowance: '0'
})

export default function allowancedialogReduceR (state = initialState, action) {
  switch (action.type) {
    case constants.SHOW_ALLOWANCE_CONFIRMATION:
      return state
        .set('confirming', true)
        .set('confirmationAllowance', action.allowance)
    case constants.HIDE_ALLOWANCE_CONFIRMATION:
      return state.set('confirming', false)
    case constants.CLOSE_ALLOWANCE_DIALOG:
      return state.set('confirming', false)
    case constants.SET_FEE_ESTIMATE:
      return state.set('feeEstimate', action.estimate)
    case constants.SET_STORAGE_ESTIMATE:
      return state.set('storageEstimate', action.estimate)
    default:
      return state
  }
}

js/actions/files.js     --    action中每个事件的type类型是必需的,其他参数根据事件需要的参数自定义,引用为action.参数名 

import * as constants from '../constants/files.js'

export const showAllowanceConfirmation = allowance => ({
  type: constants.SHOW_ALLOWANCE_CONFIRMATION,
  allowance
})
export const hideAllowanceConfirmation = () => ({
  type: constants.HIDE_ALLOWANCE_CONFIRMATION
})
export const closeAllowanceDialog = () => ({
  type: constants.CLOSE_ALLOWANCE_DIALOG
})
export const setStorageEstimate = estimate => ({
  type: constants.SET_STORAGE_ESTIMATE,
  estimate
})
export const setFeeEstimate = estimate => ({
  type: constants.SET_FEE_ESTIMATE,
  estimate
})

js/components/allowancedialog.js     --    1.ui组件,负责与用户的交互,传递用户点击的事件和事件参数给reducer
                                                                 2.PropTypes from prop-types:规定参数类型,这些参数的值是action文件里面自定义的其他参数的值,line106

import PropTypes from 'prop-types'
import React from 'react'
import UnlockWarning from './unlockwarning.js'
import ConfirmationDialog from './allowanceconfirmation.js'
import BigNumber from 'bignumber.js'

const AllowanceDialog = ({
  confirming,
  confirmationAllowance,
  unlocked,
  synced,
  feeEstimate,
  storageEstimate,
  actions
}) => {
  const onCancelClick = () => actions.closeAllowanceDialog()
  const onConfirmationCancel = () => actions.hideAllowanceConfirmation()
  const onConfirmClick = () => actions.setAllowance(confirmationAllowance)
  const onAcceptClick = e => {
    e.preventDefault()
    actions.showAllowanceConfirmation(e.target.allowance.value)
  }
  const onAllowanceChange = e => actions.getStorageEstimate(e.target.value)
  const dialogContents = confirming ? (
    
  ) : (
    

Buy storage on the Sia Decentralized Network

You need to allocate funds to upload and download on Sia. Your allowance remains locked for 3 months. Unspent funds are then refunded*. You can increase your allowance at any time.

Your storage allowance automatically refills every 6 weeks. Your computer must be online with your wallet unlocked to complete the refill. If Sia fails to refill the allowance by the end of the lock-in period, your data may be lost.

*contract fees are non-refundable. They will be subtracted from the allowance that you set.

SC
Estimated Fees {new BigNumber(feeEstimate).round(2).toString()} SC
Estimated Storage {storageEstimate}
) return (
{unlocked && synced ? ( dialogContents ) : ( )}
) } AllowanceDialog.propTypes = { confirmationAllowance: PropTypes.string.isRequired, confirming: PropTypes.bool.isRequired, unlocked: PropTypes.bool.isRequired, synced: PropTypes.bool.isRequired, feeEstimate: PropTypes.number.isRequired, storageEstimate: PropTypes.string.isRequired } export default AllowanceDialog

js/containers/allowancedialog.js     --    1.容器组件,负责处理用户交互的逻辑
                                                              2.connect from react-redux:将ui组件和容器组件连接起来,接受两个参数:mapStateToProps和mapDispatchToProps。前者负责展示在页面上,后者负责处理用户的响应事件,这个connect是生成与ui组件联系的容器组件,最后的括号里传入对应的ui组件。

import AllowanceDialogView from '../components/allowancedialog.js'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import {
  showAllowanceConfirmation,
  hideAllowanceConfirmation,
  closeAllowanceDialog,
  setAllowance,
  setFeeEstimate,
  getStorageEstimate
} from '../actions/files.js'

const mapStateToProps = state => ({
  unlocked: state.wallet.get('unlocked'),
  synced: state.wallet.get('synced'),
  storageEstimate: state.allowancedialog.get('storageEstimate'),
  feeEstimate: state.allowancedialog.get('feeEstimate'),
  confirmationAllowance: state.allowancedialog.get('confirmationAllowance'),
  confirming: state.allowancedialog.get('confirming')
})
const mapDispatchToProps = dispatch => ({
  actions: bindActionCreators(
    {
      getStorageEstimate,
      setFeeEstimate,
      showAllowanceConfirmation,
      setAllowance,
      hideAllowanceConfirmation,
      closeAllowanceDialog
    },
    dispatch
  )
})

const AllowanceDialog = connect(mapStateToProps, mapDispatchToProps)(
  AllowanceDialogView
)
export default AllowanceDialog

 

你可能感兴趣的:(前端框架--react)