17 March 2017

環境

Skill

事先閱讀

操作步驟

  • Create Project

    0001

    0002

  • Add Home Controller

    0003

  • Add View

    0004

  • Nuget Install React JS

    0005

  • Nuget Install RequireJS

    0001

  • download React Typescript V0.14

  • Setting Typescript config (Project Name -> Click Right ->Properties )

    0003

  • npm download redux & add Project

      npm install --save redux
    
    • 取資料夾的js加到專案

    0001

  • npm download react-redux & add Project

      npm install --save react-redux
    
    • 取資料夾的js加到專案

    0002

  • Nuget Install redux & react-redux typescript

    0003

  • npm download whatwg-fetch & add Project

      npm install whatwg-fetch
    
    • 取資料夾的js加到專案

    0004

  • Scripts folder

    0005

Example 1 Without Redux

  • View
@{
    Layout = null;
}

<html>
<head>
    <title>Hello React</title>
</head>
<body>  
    <script src="~/Scripts/require.js"></script>
    <script type="text/javascript">
        requirejs.config({
            baseUrl: '/Scripts',
            paths: {
                react: 'react/react',
                'react-dom': 'react/react-dom',
                redux: 'redux/redux',
                'components/switch-select': 'home/components/switch-select'
            }
        })

        // Load the main app module to start the app
        requirejs(["/scripts/home/app.js"]);
    </script>
    <h1>Typescript Demo</h1>
    <div id="content"></div>
</body>
</html>
  • switch-select.tsx
import * as React from 'react';

export default class SwitchSelect extends React.Component<any, any>{
    isDefault: boolean = false;

    constructor(props) {
        super(props);
        this.state = this.getDefault();
    }

    getDefault() {
        return {
            opts: [
                { value: 0, label: 'iphone' },
                { value: 1, label: 'android' },
            ]
        };
    }

    swdata(isDefault: boolean) {
        if (isDefault) {
            this.setState({
                opts: [
                    { value: 3, label: 'Leo' },
                    { value: 4, label: 'Lee' },
                ]
            })
        } else {
            this.setState(this.getDefault());
        }
        this.isDefault = isDefault;
    }

    render() {
        var items = this.state.opts || [];
        return <div>
            <select>
                {
                    items.map((item) => {
                        return <option key={'o-' + item.value} value={item.value}>{item.label}</option>
                    })
                }
            </select>
            <button type="button" onClick={e => this.swdata(!this.isDefault) } >switch</button>
        </div>
    }
}
  • app.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import SwitchSelect from 'components/switch-select';

ReactDOM.render(
    <SwitchSelect />,
    document.getElementById('content')
);

Example 2 Redux

  • switch-select-store.tsx
import {createStore} from 'redux';//, combineReducers, applyMiddleware

export enum SwitchType {
    one = 1,
    two = 2
}

export const SwitchSelectStore = createStore(
    (state, action) => {
        switch (action.type) {
            case SwitchType.one:
                return {
                    opts: [
                        { value: 0, label: 'iphone' },
                        { value: 1, label: 'android' },
                    ]
                }
            case SwitchType.two:
                return {
                    opts: [
                        { value: 3, label: 'Leo' },
                        { value: 4, label: 'Lee' },
                    ]
                }
            default:
                return state;
        }
    }, { opts: [] });
  • switch-select.tsx
import * as React from 'react';
import {SwitchSelectStore, SwitchType} from 'stores/switch-select-store';

export default class SwitchSelect extends React.Component<any, any>{
    isDefault: boolean = false;

    componentDidMount() {
        SwitchSelectStore.subscribe(() => this.forceUpdate());
        this.swdata(this.isDefault);
    }

    swdata(isDefault: boolean) {
        if (isDefault) {
            SwitchSelectStore.dispatch({ type: SwitchType.one })
        } else {
            SwitchSelectStore.dispatch({ type: SwitchType.two })
        }
        this.isDefault = isDefault;
    }

    render() {
        var items = SwitchSelectStore.getState().opts || [];
        return <div>
            <select>
                {
                    items.map((item) => {
                        return <option key={'o-' + item.value} value={item.value}>{item.label}</option>
                    })
                }
            </select>
            <button type="button" onClick={e => this.swdata(!this.isDefault) } >switch</button>
        </div>
    }
}
  • app.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import SwitchSelect from 'components/switch-select';

ReactDOM.render(
    <SwitchSelect />,
    document.getElementById('content')
);
  • View
@{
    Layout = null;
}

<html>
<head>
    <title>Hello React</title>
</head>
<body>  
    <script src="~/Scripts/require.js"></script>
    <script type="text/javascript">
        requirejs.config({
            baseUrl: '/Scripts',
            paths: {
                react: 'react/react',
                'react-dom': 'react/react-dom',
                redux: 'redux/redux',
                'components/switch-select': 'home/components/switch-select',
                'stores/switch-select-store': 'home/stores/switch-select-store'
            }
        })

        // Load the main app module to start the app
        requirejs(["/scripts/home/app.js"]);
    </script>
    <h1>Typescript Demo</h1>
    <div id="content"></div>
</body>
</html>

Example 3 react-redux

  • app.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import SwitchSelect from 'components/switch-select';
import {SwitchSelectStore} from 'stores/switch-select-store';

ReactDOM.render(
    <Provider store={SwitchSelectStore}>
        <SwitchSelect />
    </Provider>,
    document.getElementById('content')
);
  • switch-select.tsx
import * as React from 'react';
import {connect} from 'react-redux';

class SwitchSelect extends React.Component<any, any>{
    isDefault: boolean = false;

    constructor(props) {
        super(props);
    }

    componentDidMount() {
        this.swdata(this.isDefault);
    }

    swdata(isDefault: boolean) {
        if (isDefault) {
            this.props.getDefault();
        } else {
            this.props.getData();
        }
        this.isDefault = isDefault;
    }

    render() {
        var items = this.props.opts || [];
        return <div>
            <select>
                {
                    items.map((item) => {
                        return <option key={'o-' + item.value} value={item.value}>{item.label}</option>
                    })
                }
            </select>
            <button type="button" onClick={e => this.swdata(!this.isDefault) } >switch</button>
        </div>
    }
}

const mapStateToProps = (state) => state;

const mapDispatchToProps = (dispatch) => ({
    getData: () => {
        dispatch({ type: 1 });
    },
    getDefault: () => {
        dispatch({ type: 2 });
    }
});

export default connect(mapStateToProps, mapDispatchToProps)(SwitchSelect);
  • switch-select-store.tsx
import {createStore} from 'redux';//, combineReducers, applyMiddleware

export const SwitchSelectStore = createStore(
    (state, action) => {
        switch (action.type) {
            case 1:
                return {
                    opts: [
                        { value: 0, label: 'iphone' },
                        { value: 1, label: 'android' },
                    ]
                }
            case 2:
                return {
                    opts: [
                        { value: 3, label: 'Leo' },
                        { value: 4, label: 'Lee' },
                    ]
                }
            default:
                return state;
        }
    }, { opts: [] });
  • View
@{
    Layout = null;
}

<html>
<head>
    <title>Hello React</title>
</head>
<body>
    <script src="~/Scripts/require.js"></script>
    <script type="text/javascript">
        requirejs.config({
            baseUrl: '/Scripts',
            paths: {
                react: 'react/react',
                'react-dom': 'react/react-dom',
                redux: 'redux/redux',
                'react-redux': 'redux/react-redux',
                'components/switch-select': 'home/components/switch-select',
                'stores/switch-select-store': 'home/stores/switch-select-store'
            }
        })

        // Load the main app module to start the app
        requirejs(["/scripts/home/app.js"]);
    </script>
    <h1>Typescript Demo</h1>
    <div id="content"></div>
</body>
</html>
  • Result

    0006

Example 3-2 react-redux & whatwg-fetch

  • app.tsx
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import {Provider} from 'react-redux';
import SwitchSelect from 'components/switch-select';
import {SwitchSelectStore} from 'stores/switch-select-store';

ReactDOM.render(
    <Provider store={SwitchSelectStore}>
        <SwitchSelect />
    </Provider>,
    document.getElementById('content')
);
  • View
@{
    Layout = null;
}
  
<html>
<head>
    <title>Hello React</title>
</head>
<body>
    <script src="~/Scripts/require.js"></script>
    <script type="text/javascript">
        requirejs.config({
            baseUrl: '/Scripts',
            paths: {
                react: 'react/react',
                'react-dom': 'react/react-dom',
                redux: 'redux/redux',
                'react-redux': 'redux/react-redux',
                'fetch': 'whatwg-fetch/fetch',
                'components/switch-select': 'home/components/switch-select',
                'stores/switch-select-store': 'home/stores/switch-select-store'
            }
        })
  
        // Load the main app module to start the app
        requirejs(["/scripts/home/app.js"]);
    </script>
    <h1>Typescript Demo</h1>
    <div id="content"></div>
</body>
</html>
  • HomeController
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
    public ActionResult GetData()
    {
        var data = new[] {
            new { value = 5, label = "okinawa" }
            ,new { value = 6, label = "toyko" }
        };
        return Json(data, JsonRequestBehavior.AllowGet);
    }
}
  • switch-select.tsx
import * as React from 'react';
import {connect} from 'react-redux';
declare var fetch: any;
  
class SwitchSelect extends React.Component<any, any>{
    isDefault: boolean = false;
  
    constructor(props) {
        super(props);
    }
  
    componentDidMount() {
        this.swdata(!this.isDefault);
    }
  
    swdata(isDefault: boolean) {
        if (isDefault) {
            this.props.getDefault();
        } else {
            this.props.getData();
        }
        this.isDefault = isDefault;
    }
  
    render() {
        var items = this.props.opts || [];
        return <div>
            <select>
                {
                    items.map((item) => {
                        return <option key={'o-' + item.value} value={item.value}>{item.label}</option>
                    })
                }
            </select>
            <button type="button" onClick={e => this.swdata(!this.isDefault) } >switch</button>
        </div>
    }
}
  
const mapStateToProps = (state) => state;
  
const mapDispatchToProps = (dispatch) => ({
    getData: () => {
        dispatch({ type: 1 });
    },
    getDefault: () => {
        //dispatch({ type: 2 });
        getDefaultData(dispatch);
    }
});
  
function getDefaultData(dispatch) {
    fetch('/home/GetData')
        .then((response) => response.json())
        .then(function (json) {
            return dispatch({ type: -1, data: json });
        }).catch(function (ex) {
            console.log('parsing failed', ex)
        })
}
  
export default connect(mapStateToProps, mapDispatchToProps)(SwitchSelect);
  • switch-select-store.tsx
import {createStore} from 'redux';//, combineReducers, applyMiddleware
  
export const SwitchSelectStore = createStore(
    (state, action) => {
        switch (action.type) {
            case 1:
                return {
                    opts: [
                        { value: 0, label: 'iphone' },
                        { value: 1, label: 'android' },
                    ]
                }
            case 2:
                return {
                    opts: [
                        { value: 3, label: 'Leo' },
                        { value: 4, label: 'Lee' },
                    ]
                }
            case -1:
                return { opts: action.data }
            default:
                return state;
        }
    }, { opts: [] });
  • Result

    0007

參考資料



blog comments powered by Disqus