react-redux与mobx

react中的状态管理有很多,我们今天讲的是react-redux 和 mobx。

一:mobx

1、根目录

index.js

import { Provider } from 'mobx-react'

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

app.js

import { Provider } from 'mobx-react'

render() {
    //const newState = new AppStore()
    return (
      <Provider {...this.props}>
        <BrowserRouter history={history} basename="/">
          <div className="App">
            {/* <TopView /> */}
            <div className="mainContain">
              <RouterConfig />
            </div>
          </div>
        </BrowserRouter>
      </Provider>
    )
  }

2、appStore文件

import { observable, computed, action } from 'mobx';

@observable:值可以是JS基本数据类型、引用类型、普通对象、类实例、数组和映射。其修饰的state会暴露出来供观察者使用

@observable 接受任何类型的 js 值(原始类型、引用、纯对象、类实例、数组和、maps),observable 的属性值在其变化的时候 mobx 会自动追踪并作出响应。

当 value 是一个对象类型值的时候,它会默认克隆该对象并且把其中每个属性变为可观察的值,这里默认是深拷贝,也就是说其对象的后代属性都会变成可观察的,比如 @observable classProperty = { obj: { name: 'q' } } ,当 classProperty.obj.name 改变的时候,在 MobX 中也是可以观察到并响应的;

当然在这里可以加一些调节器来做一些配置:

  • @observable.deep (默认)对对象进行深拷贝;
  • @observable.shallow 它只对对象进行浅拷贝;
  • @observable.ref 禁用对象的自动转化,只转化其引用;

@action:只有在 actions 中,才可以修改 Mobx 中 state 的值,支持异步
注意:当你使用装饰器模式时,@action 中的 this 没有绑定在当前这个实例上,要用过 @action.bound 来绑定 使得 this 绑定在实例对象上。

@computed get TodoListCount() {

        return this.todos.length;

  }

autorun

在上面的例子中,当触发了可观察状态属性的改变后,其变化的监听则是在传入 autorun 函数中作出响应。

autorun 接受一个函数作为参数,在使用 autorun 的时候,该函数会被立即调用一次,之后当该函数中依赖的可观察状态属性(或者计算属性)发生变化的时候,该函数会被调用,注意,该函数的调用取决的函数中使用了哪些可观察状态属性(或者计算属性)。

componentDidMount() {
    const { store } = this.props
    var that = this
    autorun(() => {
      console.log('11', store.name)
      that.setState({
        numbers: store.name
      })
    })
  }

3、组件中引入:

import { observer, inject } from 'mobx-react'

@inject('store')

@observer

//获取store

    const { store } = this.props

    store.setWarnFlag(false)

class appStore {
  @observable socketUrl = 'kc.tianren.com:6060/ws'
  @action setSocketUrl(socketUrl) {
    this.socketUrl = parseInt(socketUrl)
  }
  @observable nowIndex = 0
  @observable childNowIndex = 5
  @action setIndex(nowIndex) {
    this.nowIndex = parseInt(nowIndex)
  }
  @action setChildIndex(childNowIndex) {
    this.childNowIndex = parseInt(childNowIndex)
  }
  @observable flag = false
  @action setFlag(flag) {
    this.flag = flag
  }
  @observable warnFlag = true
  @action setWarnFlag(warnFlag) {
    this.warnFlag = warnFlag
  }
  @observable todos = [
    {
      name: `李四`,
      age: 1
    }
  ] //todos列表
  @action fetchTodos() {
    var randomAge = Math.random(10)
    this.todos.push({
      name: `张三${randomAge}`,
      age: randomAge
    })
  }
  @action fetchTodoRemove() {
    this.todos.pop()
  }

  //添加
  @action AddTodo = () => {
    this.fetchTodos()
  }

  //删除单个
  @action remove() {
    this.fetchTodoRemove()
  }

  //计算长度
  @computed get TodoListCount() {
    return this.todos.length
  }
}
const AppStore = new appStore()
export default AppStore

二:Redux

index.js//

import { Provider } from 'react-redux'
import { createStore } from 'redux';
import testReducer from './store/reducer'
const store = createStore(testReducer)

Home.js//

import { connect } from "react-redux"
import { setName, getName, resetName } from '../store/actions'

setA(name) {
    console.log('sss')
    this.props.setName(name)
}

function mapStateToProps(state) {
  return {
    name: state.name
  };
}
const mapDispatchToProps = {
  setName,
  getName,
  resetName
};
export default connect(mapStateToProps, mapDispatchToProps)(Home)
reduce //
import { SET_NAME, GET_NAME, RESET_NAME } from './actions'
const finialState = {
  name: '未设置'
};

export default function testReducer(state = finialState, actions) {
  switch (actions.type) {
    case GET_NAME:
      return {
        name: `my name is ${state.name}`
      }
    case SET_NAME:
      return {
        name: actions.preload.value
      }
    case RESET_NAME:
      return {
        name: '未设置'
      }
    default:
      return state;
  }
} 

//rootReducer
import { combineReducers } from "redux";
export default combineReducers({
  products
});

同样注意 Redux 如何传递了一个 undefined 的 state,同时 action 是一个有 type 属性的对象。
我们稍后会更多地讨论 actions。现在,我们先看看 reducer。

记住 reducer 的职责是接收当前 state 和一个 action 然后返回新的 state。

const initialState = {
  count: 0
};
function reducer(state = initialState, action) {
  console.log('reducer', state, action);
  return state;
}

Actions 的格式非常自由。只要它是个带有 type 属性的对象就可以了。

另一个关于 reducers 的规则是它们必须是纯函数。也就是说不能修改它们的参数,也不能有副作用(side effect)。必须返回一个 state,不要改变 state

const store = createStore(reducer);
store.dispatch({ type: "INCREMENT" });

要做到这一点,要用到 react-redux 库的两样东西:一个名为 Provider 的组件和一个 connect 函数。

function mapStateToProps(state) {
  return {
    count: state.count
  };}

 export default  connect(mapStateToProps)(Counter);    

这样写是因为 connect 是一个高阶函数,它简单说就是当你调用它时会返回一个函数。然后调用返回的函数传入一个组件时,它会返回一个新(包装的)组件。

固执的 Redux 只接受简单对象作为 actions。

“thunk” 是(少见)指被其它函数作为返回值的函数。你可以像其他 action 生成器一样 dispatch 这些 “thunk actions”:dispatch(getUser())。

function doStuff() {
  return function(dispatch, getState) {
    // 在这里 dispatch actions
    // 或者获取数据
    // 或者该干啥干啥
  }}

Action 生成器返回的函数接收两个参数:dispatch 函数和 getState。

大多数场景你只需要 dispatch,但有时你想根据 Redux state 里面的值额外做些事情。这种情况下,调用 getState() 你就会获得整个 state 的值然后按需所取。

export function fetchProducts() {
  return dispatch => {
    dispatch(fetchProductsBegin());
    return fetch("/products")
      .then(res => res.json())
      .then(json => {
        dispatch(fetchProductsSuccess(json.products));
        return json.products;
      })
      .catch(error => dispatch(fetchProductsFailure(error)));
  };
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值