React+TypeScript+Mobx+AntDesignMobile for Mobile Project Build

Preface:

Based on React+TypeScript+Mobx+AntDesignMobile technology stack, this paper uses Create-React-App scaffolding to build a mobile-end project. It mainly introduces the project building process and related configuration, as well as the use of the status management tool Mobx. Finally, it implements the small functions of click button number+1 and a simple TodoList, which I hope you can have someHelped. GitHub code address

Specific steps for project construction:

  • Install the Create-React-App scaffolding tool, please ignore the installed students

    npm install create-react-app -g

  • Create Initial Project
    create-react-app my-app --typescript

    Be careful:
    If you are building a react project by referring to the official document of typescript, you can use the command create-react-app my-app --scripts-version=react-scripts-ts to create it. Don't use it. It's obsolete now.
    Problem with webpack version, follow-up configuration with unexpected pits Official Web in TypeScript

  • Introducing AntDesignMobile to load components on demand

    This step has a more detailed description of the official website, I will not list the configuration process one by one. I recommend that you do not expose all the built-in configurations by eject. It may be difficult to upgrade and maintain later versions. We recommend using the react-app-rewired plug-in to configure it. AntDesignMobile website

  • Install React routing, state management tool mobx, configure sass

        npm install history @types/history react-router-dom @types/react-router-dom // Install react routing
        npm install mobx-react mobx  // Install mobx
        npm install node-sass // Install the sass tool, no additional sass configuration is required after installation, the scaffolding tools are integrated
        
  • Basic configuration complete, running project
    npm run start

React Status Management Tool Mobx Introduction:

Mobx is a powerful state management tool based on object-oriented programming and relatively easy to get started with.Even the author of Redux has recommended it to you. It's friendly to support TypeScript. Refer to a flowchart on the official website:
Official Web in Mobx

Here are a few core Mobx concepts

Observable state

MobX adds observable functionality to existing data structures such as objects, arrays, and class instances.This can be done simply by annotating your class properties with the @observable decorator (ES.Next).

import { observable } from "mobx";
class Todo {
    id = Math.random();
    @observable title = "";
    @observable finished = false;
}
Computed values

With MobX, you can define values that automatically update when related data changes.Use it through the @computed decorator or by using the getter / setter function called when (extend)Observable. In the code below, MobX listens for data changes to ensure that the fooProps method is automatically updated by Computed when queue or refresh changes.

import React from 'react';
import {observable, isArrayLike, computed, action, autorun, when, reaction,runInAction} from "mobx";
import {observer} from 'mobx-react';

// Define Data Store
class Store {
    @observable queue:number = 1;
    @action refresh = ():void => {
        this.queue += 1;
        console.log('this.queue -> ', this.queue);
    }
    @computed get fooProps():any {
        return {
            queue: this.queue,
            refresh: this.refresh
        };
    }
  }
Actions

Any application has actions.Actions are anything that modifies a state, and mobx recommends placing actions that modify observed variables in an action.Actions can only affect functions that are running, not the asynchronous operation of the current function call. Refer to the official documentation for usage:

action(fn)
action(name, fn)
@action classMethod() {}
@action(name) classMethod () {}
@action boundClassMethod = (args) => { body }
@action(name) boundClassMethod = (args) => { body }
@action.bound classMethod() {}
action Decorator/Function follows javascript Medium standard binding rules.However, action.bound Actions can be automatically bound to the target object.Note that with action The difference is,(@)action.bound No need for one name Parameter, name will always be based on action-bound properties.
class Ticker {
    @observable tick = 0

    @action.bound
    increment() {
        this.tick++ // 'this'is always correct
    }
}

const ticker = new Ticker()
setInterval(ticker.increment, 1000)

Two small functions using Mobx as state management

Click button+1
import React from 'react';
import {observable, isArrayLike, computed, action, autorun, when, reaction,runInAction} from "mobx";
import {observer} from 'mobx-react';
import {Button} from 'antd-mobile';
import './index.scss';

// Define a data Store using Mobx as a state management tool
class Store {
    @observable queue:number = 1;
    @action refresh = ():void => {
        this.queue += 1;
        console.log('this.queue -> ', this.queue);
    }
    @computed get fooProps():any {
        return {
            queue: this.queue,
            refresh: this.refresh
        };
    }
  }
// The ts component must define the interface type to receive the data passed by the parent component, otherwise an error will occur
interface BarProps{
    queue :number
}
// @observer modifier class, the Bar component accepts the queue attribute passed from the Foo group
@observer 
class Bar extends React.Component<BarProps>{
    render() {
        const {queue} = this.props
        return (
            <div className="queue">{queue}</div>
        )
    }
}
interface FooProps {
    queue: number,
    refresh():void
}
// The Foo component receives store data from the Add component
@observer
class Foo extends React.Component<FooProps>{
    render() {
        const {queue,refresh} = this.props;
        return (
            <div>
                <Button type="primary" onClick = {refresh}>Refresh</Button>
                <Bar queue = {queue} />
            </div>
        )
    }
}
// Initialize store data, pass to Foo component
const store = new Store();
class Add extends React.Component{
    render() {
        return (
            <div>
                <h2 className="add"> hello react-ts-mobx</h2>
                <Foo queue = {store.queue} refresh = {store.refresh} />
            </div>
           
        )
    }
}
export default observer(Add)
TodoList functionality
import React from 'react';
import {observable, isArrayLike, computed, action, autorun, when, reaction,runInAction} from "mobx";
import {observer} from 'mobx-react';
import './index.scss';
// Define Todo data type
class Todo {
    id:number = new Date().getTime();
    title:string = '';
    finished:boolean = false;
    constructor(title:string) {
        this.title = title;
    }
}
// Store Data Method Management
class Store {
    @observable title:string = '';
    @observable todos:Todo[] =[];
    // Title to add Todo
    @action createTitle (e:any) {
        console.log('e',e.target.value);
        this.title = e.target.value;
    }
    // Increase Todo Data
    @action createTodo = () => {
        this.todos.unshift(new Todo(this.title));
        this.title = '';
    }
    // Delete Todo
    @action delTodo (id:number) {
        this.todos.forEach((item,index) => {
            if (item.id === id) {
                this.todos.splice(index,1)
            }
        })
    }
    // Monitor todos data changes to show remaining to-dos
    @computed get unfinished () {
        return this.todos.filter(todo => !todo.finished).length;
    }

}
interface TodoItemProps {
    todo:any;
    store:any;
}
// Each Todo Data Component
@observer 
class TodoItem extends React.Component<TodoItemProps> {
    render() {
        const {todo,store} = this.props
        return (
            <div className="item">
               <span>{todo.title}</span>
               <span onClick={()=> store.delTodo(todo.id)}>X</span>
            </div>
        )
    }
}
const store = new Store();
@observer 
class TodoList extends React.Component {
    render() {
        return (
            <div>
                <h2>TodoList</h2>
                <header>
                    <input type="text" placeholder="please input" value={store.title} onChange = {e => store.createTitle(e)} />
                    <button onClick ={store.createTodo}>add</button>
                </header>
                <ul>
                    {store.todos.map((todo)=>{
                        return <li key={todo.id}>
                           <TodoItem todo={todo} store = {store}/>
                        </li>
                    })}
                </ul>
                <footer>
                 {store.unfinished} item(s) unfinished
                </footer>
            </div>
        )
    }
}
export default TodoList

Summary:

I have just come into contact with TypeScript and Mobix and summarized my learning methods: I should be familiar with some basic concepts, slowly do some small functions, think carefully after encountering problems, check the data or consult others, read the documents repeatedly to strengthen the understanding of knowledge; welcome the big guys to leave a message and exchange; GitHub code address

Keywords: Javascript React TypeScript sass npm

Added by validangina on Sun, 30 Jun 2019 19:30:13 +0300