最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】ReactJS中用Mobx实现最基本的状态管理

ReactJS crifan 2617浏览 0评论

 折腾:

【未解决】尝试用Mobx实现ReactJS中的全局数据共享

期间,先要去实现,用Mobx去实现最基本的状态管理:

即,代码中取出了setState这类函数,让Mobx自动通过变量的定义

变量的@observable

函数的@observer:自动识别变量变化了后去更新类的render函数

然后才能去折腾更高级的实现全局状态,全局变量的管理。

参考:

1. MobX 介绍 · MobX 中文文档

参考:

How to (not) use decorators | MobX

去添加ES.next的支持

此处我的是babel,所以去

npm i –save-dev babel-plugin-transform-decorators-legacy

➜  rse_web git:(master) ✗ npm i –save-dev babel-plugin-transform-decorators-legacy
[email protected] /Users/crifan/dev/dev_root/xxx
npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed.
npm WARN [email protected] requires a peer of react@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^15.5.4 but none was installed.

然后再去

.babelrc

添加配置:

{
  “presets”: [
    “env”,
    “stage-0”,
    “react”,
    “es2015”,
    “stage-1”
  ],
  “plugins”: [
    “transform-decorators-legacy”,
    “transform-runtime”,
    “react-hot-loader/babel”
  ]
}

结果VSCode中代码警告:

【已解决】VSCode中js中@observable警告:Set the experimentalDecorators option to remove this warning

再去安装库:

➜  rse_web git:(master) ✗ npm install mobx mobx-react –save
[email protected] /Users/crifan/dev/dev_root/xxx
  └── [email protected]
npm WARN [email protected] requires a peer of react@^15.6.1 but none was installed.
npm WARN [email protected] requires a peer of react@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react@^15.5.4 but none was installed.
npm WARN [email protected] requires a peer of react-dom@^15.5.4 but none was installed.

看了半天文档,还是不太懂

react js mobx 教程

MobX 入门教程 · Issue #2 · sorrycc/blog

Mobx使用详解 – 简书

然后去试了试,结果出错:

【已解决】ReactJS中使用Mobx出错:Module build failed Error Couldn’t find preset es2015 relative to directory

但是又出错:

【已解决】ReactJS中出错:Decorators are not officially supported yet in 6.x pending a proposal update

【总结】

通过前面的:

然后去代码中:

实现了用Mobx去管理基本的状态了:

当数据发生变化,可以自动检测并更新数据了:

login.js

import React, { Component } from ‘react’;
import ‘./login.less’;
import BodyClassName from ‘react-body-classname’;
import { stopEventPropgation } from ‘lib/eventHelper’;
import { ROUTE_PREFIX, EMPTY_USER_INFO } from ‘common/define’;
// import PropTypes from ‘prop-types’;
import { withRouter, Redirect } from ‘react-router-dom’;
import AppGlobal from ‘common/app-global’;
import { observable, computed } from ‘mobx’;
import { observer } from ‘mobx-react’;
@observer
export default class Login extends Component {
// class Login extends Component {
  // state = {
  //   curUserInfo: EMPTY_USER_INFO
  //   // loginCallback: null
  // };
  // state = {
  //   account: AppGlobal.curUserInfo.account,
  //   password: AppGlobal.curUserInfo.password,
  //   isLogin: AppGlobal.curUserInfo.isLogin,
  // }
  @observable account = AppGlobal.curUserInfo.account;
  @observable password = AppGlobal.curUserInfo.password;
  @observable isLogin = AppGlobal.curUserInfo.isLogin;
  constructor(props) {
    super(props);
    console.log(‘Login constructor’,
      ‘props=’, props,
      ‘props.match=’, props.match,
      ‘props.history=’, props.history,
      ‘props.location=’, props.location,
      ‘props.location.state’, this.props.location.state);
    // this.state.curUserInfo = this.props.location.state.curUserInfo;
    // console.log(this.state.curUserInfo);
    this.submitLogin = this.submitLogin.bind(this);
    this.onAccountChange = this.onAccountChange.bind(this);
    this.onPasswordChange = this.onPasswordChange.bind(this);
    //for debug
    // this.state.curUserInfo.account = ‘13900001111’;
    // this.state.curUserInfo.password = ‘666666’;
    // AppGlobal.curUserInfo.account = ‘13900001111’;
    // AppGlobal.curUserInfo.password = ‘666666’;
  }
  submitLogin(e){
    console.log(‘Login submitLogin: e=’, e);
    //Note: here stopEventPropgation include e.preventDefault();, to prevent event propgate to browser
    // otherwise:
    // (1) Chrome will warning: Form submission canceled because the form is not connected
    // (2) Safari will redirect to refresh page -> here will cause resource not found 404 error
    stopEventPropgation(e);
    //TODO: call API to login
    // this.setState({isLogin : true});
    // AppGlobal.curUserInfo.isLogin = this.state.isLogin;
    // AppGlobal.curUserInfo.account = this.state.account;
    // AppGlobal.curUserInfo.password = this.state.password;
    this.isLogin = true;
    // AppGlobal.curUserInfo.isLogin = this.state.isLogin;
    // AppGlobal.curUserInfo.account = this.state.account;
    // AppGlobal.curUserInfo.password = this.state.password;
    //for debug
    // this.setState({
    //   curUserInfo: {
    //     isLogin: true,
    //     account: ‘13900001111’,
    //     password: ‘666666’,
    //     orgCode: ‘SK316005’,
    //     name: ‘hyq’,
    //     roleName: ‘商务总监’,
    //     loginTime: new Date()
    //   }
    // });
    AppGlobal.curUserInfo = {
      isLogin: true,
      account: ‘13900001111’,
      password: ‘666666’,
      orgCode: ‘SK316005’,
      name: ‘hyq’,
      roleName: ‘商务总监’,
      loginTime: new Date()
    };
    // if (this.state.loginCallback) {
    //   // return login user info to Index
    //   this.state.loginCallback(this.state.curUserInfo);
    // }
    // if (this.props.history) {
    //   console.log(`jump to path: ${ROUTE_PREFIX.WELCOME}`);
    //   this.props.history.push(ROUTE_PREFIX.WELCOME);
    // }
  }
  onAccountChange(e){
    console.log(‘onAccountChange: e=’, e, ‘ ,e.target.value=’, e.target.value, `this.account=${this.account}`);
    // this.setState({
    //   curUserInfo : {
    //     account : e.target.value
    //   }
    // });
    // this.setState({
    //   account : e.target.value
    // });
    this.account = e.target.value;
  }
  onPasswordChange(e){
    console.log(‘onPasswordChange: e=’, e, ‘, e.target.value=’, e.target.value, `this.password=${this.password}`);
    // this.setState({
    //   curUserInfo : {
    //     password : e.target.value
    //   }
    // });
    // this.setState({
    //   password : e.target.value
    // });
    this.password = e.target.value;
  }
  render() {
    // console.log(`Login render: this.state.curUserInfo.isLogin=${this.state.curUserInfo.isLogin}`);
    console.log(‘Login render: AppGlobal.curUserInfo.isLogin=’, AppGlobal.curUserInfo.isLogin);
    console.log(`account=${this.account},password=${this.password},isLogin=${this.isLogin}`);
    let loginBodyClass = ‘hold-transition login-page’;
    // state: {
    //   curUserInfo: this.state.curUserInfo
    // }
    return (
      this.isLogin ?
      <Redirect to={
        {
          pathname: ROUTE_PREFIX.WELCOME
        }
      }/>
      :
      <BodyClassName className={loginBodyClass}>
        <div className=”login-box”>
          <div className=”login-logo”>
            <a href=”#”><b>xxx</b>RSE</a>
          </div>
  
          <div className=”login-box-body”>
            <p className=”login-box-msg”>请登录</p>
            <form onSubmit={this.submitLogin}>
              <div className=”form-group has-feedback”>
                <input
                  value={this.account}
                  type=”text”
                  className=”form-control”
                  placeholder=”账号”
                  onChange={this.onAccountChange}
                />
                <span className=”glyphicon glyphicon-envelope form-control-feedback”></span>
              </div>
  
              <div className=”form-group has-feedback”>
                <input
                  value={this.password}
                  type=”password”
                  className=”form-control”
                  placeholder=”密码”
                  onChange={this.onPasswordChange}
                />
                <span className=”glyphicon glyphicon-lock form-control-feedback”></span>
              </div>
  
              <div className=”row”>
                <div className=”col-xs-12″>
                <button type=”submit” className=”btn btn-primary btn-block btn-flat”>登录</button>
                </div>
              </div>
  
              <br />
              <a href=”https://shimo.im/doc/0kbgLWxVgQYQbjMi”;; target=’_blank’>
                <p className=”rse_help”>RSE帮助</p>
              </a>
            </form>
          </div>
        </div>
      </BodyClassName>
    );
  }
}
// Login.contextTypes = {
//   router: PropTypes.object.isRequired
// };
// export default withRouter(Login);
withRouter(Login);

app-global.js中:

import { EMPTY_USER_INFO } from ‘./define’;
import { urlEncodeParam } from ‘lib/httpHelper’;
import { observable, computed } from ‘mobx’;
import { observer } from ‘mobx-react’;
class AppGlobal {
  @observable curUserInfo = EMPTY_USER_INFO;
  constructor() {
    // // for debug
    // this.curUserInfo = {
    //   isLogin: true,
    //   account: ‘13918582683’,
    //   password: ‘666666’,
    //   orgCode: ‘SK316005’,
    //   name: ‘何雅秋’,
    //   roleName: ‘商务总监’,
    //   loginTime: new Date()
    // };
    console.log(`AppGlobal constructor`, this.curUserInfo);
  }

然后输入用户名和密码时,可以实时更新数据了:

转载请注明:在路上 » 【已解决】ReactJS中用Mobx实现最基本的状态管理

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
89 queries in 0.172 seconds, using 22.16MB memory