React third-party component 2 (the use of Refast for state management①simple use)

React third-party component 2 (the use of Refast for state management①simple use)

There are 5 articles in this tutorial, one updated daily, please follow us! You can enter the historical news to view the previous articles, and stay tuned for our new articles!

1. React third-party component 2 (use of Refast for state management①simple use) ---2018.01.29

2. React third-party component 2 (use of Refast for state management ②asynchronous modification of state) ---2018.01.30

3. React third-party component 2 (use of Refast for state management ③extended ctx) ---2018.02.31

4. React third-party component 2 (use of Refast for state management ④ use of middleware) ---2018.02.01

5. React third-party components 2 (use of Refast for state management ⑤ use of LogicRender) ---2018.02.02

Development environment: Windows 8, node v8.9.1, npm 5.5.1, WebStorm 2017.2.2

Refast is a react state management tool contributed by the Alibaba team. Its simplicity and practicality are well received by users! It did it ( React component state management tool that you can learn in 5 minutes )!

Document address: http://doc.refast.cn/

Let's use Refast today! (Don’t talk too deeply, just use it briefly)

1. Let's create a new routing page demo3:

The directory structure is as follows:

2. Create a new Index.jsx file

import React from'react';
import TodoList from'./TodoList';

const Index = () =>
    <TodoList/>
;

export default Index;

3. Copy TodoList.jsx under demo1 to demo3

4. Installation dependencies:

npm i -S refast

5. First create a logic.js file under demo3

Copy the two methods in TodoList.jsx to logic,js

handleAdd() {
    let item = this.refs['todoInput'].value;
    if (item) {
        let list = this.state.list;
        list.push({id: list.length + 1, title: item, status: 1});
        this.setState({list: list}, () => console.log(this.state.list))
    } else {
        alrt('cannot be empty')
    }
}

handleItemEdit(id, status) {
    let list = this.state.list;
    list.find(data => data.id === id).status = status;
    this.setState({list: list})
}

as follows:

//Refast uses the return value of the defaults method in logic.js to initialize the state of the component
export default {
   //The parameter props of defaults is the props when the component is initialized
   //The object returned by the defaults function will be used to initialize the state of the component
    defaults(props) {
        return {
            list: []
        }
    },
    handleAdd(ctx, title) {
        if (title) {
            let list = ctx.getState().list;
            list.push({id: list.length + 1, title: title, status: 1});
            ctx.setState({list: list});
        } else {
            alrt('cannot be empty')
        }
    },
    handleItemEdit(ctx, someState) {
        let {id, status} = someState, list = ctx.getState().list;
        list.find(data => data.id === id).status = status;
        ctx.setState({list: list})
    }
}

These two methods are also called Action. After Logic is connected to the component, the Action in Logic can be called directly through the dispatch method of the component.

It can be called like this in TodoList:

this.dispatch('handleAdd','xxxxxx')}

Pass parameters to the method through dispatch (or not pass).

The first parameter of the dispatched Action is always the context (hereinafter referred to as ctx). In addition, ctx also encapsulates the following general methods: ctx.setState sets the state of the component, and the usage is the same as the setState of the component.

So you can also write it like this:

//Refast uses the return value of the defaults method in logic.js to initialize the state of the component
export default {
   //The parameter props of defaults is the props when the component is initialized
   //The object returned by the defaults function will be used to initialize the state of the component
    defaults(props) {
        return {
            list: []
        }
    },
    handleAdd({getState, setState}, title) {
        if (title) {
            let list = getState().list;
            list.push({id: list.length + 1, title: title, status: 1});
            setState({list: list});
        } else {
            alrt('cannot be empty')
        }
    },
    handleItemEdit({getState, setState}, someState) {
        let {id, status} = someState, list = getState().list;
        list.find(data => data.id === id).status = status;
        setState({list: list})
    }
}

6. Transform TodoList.jsx

import React from'react';
import {Component} from'refast';
//Introduce logic.js
import logic from'./logic';
import'../../../public/css/todoList.pcss';

class TodoList extends Component {
    constructor(props) {
        super(props, logic);
    }

    render() {
        let {list} = this.state;
        let LiCont = ({data}) =>
            <li>
                {data.title}
                <button
                    onClick={() => this.dispatch('handleItemEdit', {
                        id: data.id,
                        status: data.status === 1? 0: 1
                    })}
                    className={data.status === 1? "del": "recovery"}>
                    {data.status === 1? "Delete": "Restore"}
                </button>
            </li>
        ;
        let ListCont = ({type}) =>
            <div className="list">
                {
                    list.map(data => [
                            type === 0?
                                <LiCont data={data} key={data.id}/>
                                :
                                type === 1 && data.status === 1?
                                    <LiCont data={data} key={data.id}/>
                                    :
                                    type === 2 && data.status === 0?
                                        <LiCont data={data} key={data.id}/>
                                        :
                                        null
                        ]
                    )
                }
            </div>
        ;
        return (
            <div className="todoList">
                <input type="text" ref="todoInput"/>
                <button onClick={() => this.dispatch('handleAdd', this.refs['todoInput'].value)}>Add</button>
                <div className="cont">
                    <div className="box">
                        All
                        <ListCont type={0}/>
                    </div>
                    <div className="box">
                        Not deleted
                        <ListCont type={1}/>
                    </div>
                    <div className="box">
                        deleted
                        <ListCont type={2}/>
                    </div>
                </div>
            </div>
        );
    }
}

export default TodoList;

Use Refast's Component instead of React's Component

Introduce logic

Binding logic through super

Look at the browser, everything should be OK!

Refast is mainly for decoupling, each has its own!

If you need to split the components, you can also write:

Let's create a new page demo4

Repeat the same steps as creating a new demo3!

TodoList.jsx:

import React from'react';
import {Component} from'refast';
//Introduce logic.js
import logic from'./logic';
import List from'./List';
import'../../../public/css/todoList.pcss';

class TodoList extends Component {
    constructor(props) {
        super(props, logic);
    }

    render() {
        let {list} = this.state, {dispatch} = this;
        return (
            <div className="todoList">
                <input type="text" ref="todoInput"/>
                <button onClick={() => this.dispatch('handleAdd', this.refs['todoInput'].value)}>Add</button>
                <div className="cont">
                    <div className="box">
                        All
                        <List type={0} list={list} dispatch={dispatch}/>
                    </div>
                    <div className="box">
                        Not deleted
                        <List type={1} list={list} dispatch={dispatch}/>
                    </div>
                    <div className="box">
                        deleted
                        <List type={2} list={list} dispatch={dispatch}/>
                    </div>
                </div>
            </div>
        );
    }
}

export default TodoList;

List.jsx:

import React from'react';

const LiCont = ({data, dispatch}) =>
    <li>
        {data.title}
        <button
            onClick={() => dispatch('handleItemEdit', {
                id: data.id,
                status: data.status === 1? 0: 1
            })}
            className={data.status === 1? "del": "recovery"}>
            {data.status === 1? "Delete": "Restore"}
        </button>
    </li>
;

const List = ({dispatch, list, type}) =>
    <div className="list">
        {
            list.map(data => [
                    type === 0?
                        <LiCont data={data} dispatch={dispatch} key={data.id}/>
                        :
                        type === 1 && data.status === 1?
                            <LiCont data={data} dispatch={dispatch} key={data.id}/>
                            :
                            type === 2 && data.status === 0?
                                <LiCont data={data} dispatch={dispatch} key={data.id}/>
                                :
                                null
                ]
            )
        }
    </div>
;
export default List;

logic.js

export default {
    defaults(props) {
        return {
            list: []
        }
    },
    handleAdd({getState, setState}, title) {
        if (title) {
            let list = getState().list;
            list.push({id: list.length + 1, title: title, status: 1});
            setState({list: list});
        } else {
            alrt('cannot be empty')
        }
    },
    handleItemEdit({getState, setState}, someState) {
        let {id, status} = someState, list = getState().list;
        list.find(data => data.id === id).status = status;
        setState({list: list})
    }
}

The directory results are as follows:

7. Test

We add these two routes to Index.jsx under the demo

Run the browser, everything is ok

import React from'react';
import {HashRouter, Route, NavLink, Redirect} from'react-router-dom'
import {BundleFun} from'../common/Bundle'
import Dome1 from'./demo1/Demo1.bundle'
import Dome2 from'./demo2/Demo2.bundle'
import Dome3 from'./demo3/Index'
import Dome4 from'./demo4/Index'
import'../../public/css/demo.pcss'

const Index = () =>
    <HashRouter>
        <div className="content">
            <div className="nav">
                <NavLink to="/Dome1" activeClassName="selected" exact>demo1</NavLink>
                <NavLink to="/Dome2" activeClassName="selected">demo2</NavLink>
                <NavLink to="/Dome3" activeClassName="selected">demo3</NavLink>
                <NavLink to="/Dome4" activeClassName="selected">demo4</NavLink>
            </div>
            <Route exact path="/"
                   render={() => (<Redirect to="/Dome1"/>)}/>
            <Route path="/Dome1" component={() => BundleFun(Dome1)}/>
            <Route path="/Dome2" component={(props) => BundleFun(Dome2, props)}/>
            <Route path="/Dome3" component={Dome3}/>
            <Route path="/Dome4" component={Dome4}/>
        </div>
    </HashRouter>
;

In the browser, see below:

Both ways of writing are OK! ! !

Reference: https://cloud.tencent.com/developer/article/1092839 React third-party component 2 (the use of Refast for state management ① simple use)-Cloud + Community-Tencent Cloud