mobx5的简单使用——异步请求数据的位置问题

mobx5

  • 建议在17及以下版本的react中去使用
  • 建议在类组件中去使用mobx5
npm i -S mobx@5 mobx-react@5 --force

mobx5就是通过装饰器来完成对于属性和方法的装饰,来实现数据的响应式

  • mobx5就是通过装饰器来完成对于属性和方法的装饰,来实现数据的响应式

定义文件夹数据源///定义mobx状态库
mobx/inde.js

// 定义一个类
class Store {
    
    
    num = 100
    setNum(n) {
    
    
        this.num += n
    }
}

// {store:store对象实例}
export default {
    
     store: new Store() }

那么在入口文件中将数据源导入:在src/index.js入口文件中引入
mobx5提供了一个组件,将数据放在注入到组件中,将数据源导入到文件当中
index.js文件:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App'
// mobx5
import {
    
     Provider } from 'mobx-react'
// {store:store实例}
import store from './mobx'

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

使用:

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

@inject(['store']) // 把store映射到this.props.store中
class App extends Component {
    
    
    render() {
    
    
        return (
            <div>
                <h1>{
    
    this.props.store.num}</h1>
                <button onClick={
    
    e=>{
    
    this.props.store.setNum(2)}}>+ +</button>
            </div>
        );
    }
}

export default App;

在这里插入图片描述
可以发现数据没有响应,那么我们应该让数据变为响应式,组件也变为响应式。

  • mobx-react提供了高阶组件observer来完成这项工作。
  • observable:让组件变化是一个响应式的组件, 让此属性变成一个响应式的属性
  • action让方法变为响应式的方法

响应式属性设置:

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

// 定义一个类
class Store {
    
    
	// 让此属性变成一个响应式的属性
    @observable
    num = 100
    
    // action让成员方法,变成一个可以操作响应数据的方法
    @action
    setNum(n) {
    
    
        this.num += n
        console.log(n,this.num);
    }
}

// {store:store对象实例}
export default {
    
     store: new Store() }

完成响应式的使用写法:

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

@inject(['store']) // 把store映射到this.props.store中
@observer // 1.让组件变化是一个响应式的组件
class App extends Component {
    
    
    render() {
    
    
        return (
            <div>
                <h1>{
    
    this.props.store.num}</h1>
                <button onClick={
    
    e=>{
    
    this.props.store.setNum(2)}}>+++</button>
            </div>
        );
    }
}

export default App;

复杂数据类型的简单使用

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

// 定义一个类
class Store {
    
    
    @observable
    num = 100;

    @action.bound
    setNum(n) {
    
    
        this.num += n;
        console.log(n, this.num);
    }

    @observable 
    users = [];

    @action
    setUsers(data) {
    
    
        this.users.push(data);
    }
}

// {store:store对象实例}
export default {
    
     store: new Store() };
<h2>{
    
    JSON.stringify(this.props.store.users)}</h2>
<ul>
    {
    
    
        this.props.store.users.map(item=>(
            <li key={
    
    item.name}>name:{
    
    item.name}</li>
        ))
    }

</ul>
<button onClick={
    
    e=>{
    
    this.props.store.setUsers({
    
    name:Date.now()})}}>添加姓名</button>

在这里插入图片描述


但是我们发现这个函数的使用直接前面需要写很多的链式寻找:我们解构之后需要注意的是修改方法里的this指向问题.bound解决这个问题:
虽然可以解决this指向问题,但一般解构后使用此方法才会有this指向不对问题。来解决

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

// 定义一个类
class Store {
    
    
    @observable
    num = 100;

    @action.bound
    setNum(n) {
    
    
        this.num += n;
        console.log(n, this.num);
    }

    @observable 
    users = [];

    @action.bound
    setUsers(data) {
    
    
        this.users.push(data);
    }
}

// {store:store对象实例}
export default {
    
     store: new Store() };

假如现在有异步操作,当然可以直接在主程序中请求,然后在给mobx方法用来修改源数据:
但是不建议:可以在mobx方法中来完成对数据的异步操作;
尝试网络请求:

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

// 定义一个类
class Store {
    
    

    @observable 
    users = [];

    @action.bound
    async setUsers(n) {
    
    
        let data = await loadtime(n);//设置一个异步阻塞,发现可以实现网络请求
        this.users.push({
    
    name:Date.now()});
    }
}
function loadtime(n){
    
    
    return new Promise(_=>{
    
    
        setTimeout(() => {
    
    
            _("")
        }, n);
    })
}
// {store:store对象实例}
export default {
    
     store: new Store() };
+++++++++++++++++++
app.jsx
<button onClick={
    
    e=>{
    
    setUsers(3000)}}>添加姓名</button>

n秒之后就完成数据的传入:可行


接着,如果脚手架没有设置axios或者http,可以使用webpack提供的全局fetch来进行网络请求,配置一个代理,完成对网络数据的模拟请求;

@action.bound
async setUsers(n) {
    
    
    let data = await loadtime(n);//设置一个异步阻塞,发现可以实现网络请求
    let ret = await (await fetch('/api/users?name='+n)).json()//网络请求模拟mock
    console.log(ret.data);
    this.users.push({
    
    name:Date.now()},...ret.data);
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/m0_46672781/article/details/127326390