19-React-01 快速學(xué)習(xí)與基本使用

一、React 相關(guān)概念:

1.1. 含義:
  • React 是一個用于構(gòu)建用戶界面的JavaScript庫。
  • React主要用于構(gòu)建UI,很人多認為 React 是 MVC 中的 V(視圖)。
  • React 起源于 Facebook 的內(nèi)部項目,用來架設(shè) Instagram 的網(wǎng)站,并于 2013 年 5 月開源。
  • React 擁有較高的性能,代碼邏輯非常簡單,越來越多的人已開始關(guān)注和使用它。
1.2. 作用:
  • 用做UI: 許多人把React當(dāng)做MVC設(shè)計模式中的視圖(view),當(dāng)把React成為你的技術(shù)掌握之后, 它可以很輕松應(yīng)用于一個小功能的項目。
  • 虛擬DOM:React用一個”虛擬DOM”實現(xiàn)了超高的性能,配合nodeJS也可以實現(xiàn)在服務(wù)端的渲染,不存在耗時的瀏覽器dom渲染。
  • 數(shù)據(jù)流: React是一種減少引用數(shù)據(jù)流的實現(xiàn)方式,并且比傳統(tǒng)的方式更容易實現(xiàn)數(shù)據(jù)綁定。
  • React Native 項目就是使用 React 和 JavaScript 創(chuàng)建本機 APP。
1.3. 特點:
  • 聲明式設(shè)計 ?React采用聲明范式,可以輕松描述應(yīng)用。
  • 高效 ?React通過對DOM的模擬,最大限度地減少與DOM的交互。
  • 靈活 ?React可以與已知的庫或框架很好地配合。
  • JSX ? JSX 是 JavaScript 語法的擴展。React 開發(fā)不一定使用 JSX ,但我們建議使用它。
  • 組件 ? 通過 React 構(gòu)建組件,使得代碼更加容易得到復(fù)用,能夠很好的應(yīng)用在大項目的開發(fā)中。
  • 單向響應(yīng)的數(shù)據(jù)流 ? React 實現(xiàn)了單向響應(yīng)的數(shù)據(jù)流,從而減少了重復(fù)代碼,這也是它為什么比傳統(tǒng)數(shù)據(jù)綁定更簡單。

二、安裝

  • 關(guān)于安裝這里不再贅述,你可以在官網(wǎng) http://facebook.github.io/react/ 下載最新版;
  • 也可以直接使用 cdn 上的React CDN 庫,地址如下:
<script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
說明:
1.react.min.js - React 的核心庫;
2.react-dom.min.js - 提供與 DOM 相關(guān)的功能;
3.browser.min.js - 用于將 JSX 語法轉(zhuǎn)為 JavaScript 語法,關(guān)于 JSX 語法在下面說明。

三、 React JSX 語法說明

  • JSX 的語法如下:
ReactDOM.render(
    <h1>Hello, world!</h1>,
    document.getElementById('example')
);
以上代碼將一個 h1 標(biāo)題,插入 id="example" 節(jié)點中。
如果我們需要使用 JSX,則 <script> 標(biāo)簽的 type 屬性需要設(shè)置為 text/babel。
我們可以在 JSX 中使用 JavaScript 表達式。表達式寫在花括號 {} 中
  • 完整示例:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
    <div id="em1"></div>
    <script type="text/babel">
        ReactDOM.render(
            <h1>Hello, YijiangWang! {1+2}</h1>,
            document.getElementById('em1')
        )
    </script>
</body>
</html>

四、 組件

  • 通過方法 React.createClass 方法用于生成一個組件類;
  • 如果我們需要向組件傳遞參數(shù),可以使用 this.props 對象,實例如下:
var Yjw_component = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

ReactDOM.render(
  <Yjw_component name="Yjw" />,
  document.getElementById('example')
);
注意:
  1.原生 HTML 元素名以小寫字母開頭,而自定義的 React 類名以大寫字母開頭;
  2.組件類只能包含一個頂層標(biāo)簽,否則也會報錯。
  • 復(fù)合組件:
//自定義符合組件
/**
*   注意點:
 *   1、組件首字母要大寫
 *   2、不能 return 多個控件,如果需要返回多個控件,可以在最外層用一個控件進行包裝
 *   3、return 控件時,要用 () 進行包裝
* */
var Contenttxt = React.createClass({
    render:function () {
        return (
                <h1>{this.props.contentt}</h1>
        )
    }
});
var Titletxt = React.createClass({
    render:function () {
        return (
                <h2>{this.props.titlet}</h2>
        )
    }
});

var Article = React.createClass({
    render:function () {
        return (
            <div>
                <Titletxt titlet={this.props.titlet} />
                <Contenttxt contentt={this.props.contentt} />
            </div>
        )
    }
});

ReactDOM.render(
    <Article titlet="I'm the title" contentt="I'm the content"></Article>,
        document.getElementById("example")
)

五、React State(狀態(tài))

//自定義一個組件
var Yjw = React.createClass({
    //定義初始狀態(tài)
    getInitialState:function () {
        return {like:true};
    },
    //定義一個點擊事件
    handle:function () {
        this.setState({like:!this.state.like})
    },
    render:function () {
        var text = this.state.like?"喜歡":"不喜歡";
        return (
                <h1 onClick={this.handle}>{this.props.titlet}如果你 <ins>{text}</ins> 我,就點我</h1>
        )
    },
});

//渲染一個組件
ReactDOM.render(
        <Yjw/>,
        document.getElementById("example")
)

六、React Props

  • 設(shè)置默認 props
var Dprop = React.createClass({
    getDefaultProps:function () {
        return {
            name:"yijiang"
        }
    },

    render:function () {
        return (
                <h1>這里是默認的:{this.props.name}</h1>
        )
    }
});
ReactDOM.render(
        <Dprop name="mage"/>,
        document.getElementById("prop1")
);
  • props 和 state 結(jié)合使用
var Name = React.createClass({
    render:function () {
        return <h1>I'm {this.props.name}</h1>
    }
});

var Site = React.createClass({
    render:function () {
        return <a href={this.props.site}>{this.props.site}</a>
    }
});

var Website = React.createClass({
    getInitialState:function () {
        return {
            name:"yijiang",
            site:"www.baidu.com"
        }
    },

    clickName:function () {
        this.setState({name:"magege"});
    },

    render:function () {
        return (
                <div onClick={this.clickName}>
                    <Name name={this.state.name}/>
                    <Site site={this.state.site}/>
                </div>
        )
    }
});

ReactDOM.render(
        <Website/>,
        document.getElementById("prop2")
);
  • prop 驗證:這里驗證 title 必須為 string 類型,并且是必須字段:
var Vprop = React.createClass({
    propTypes:{
        title:React.PropTypes.string.isRequired
    },

    render:function () {
        return (<h1>{this.props.title}</h1>)
    }
});

ReactDOM.render(
        <Vprop title="123"/>,
        document.getElementById("prop3")
)
更多的驗證器說明如下
React.createClass({
  propTypes: {
    // 可以聲明 prop 為指定的 JS 基本數(shù)據(jù)類型,默認情況,這些數(shù)據(jù)是可選的
   optionalArray: React.PropTypes.array,
    optionalBool: React.PropTypes.bool,
    optionalFunc: React.PropTypes.func,
    optionalNumber: React.PropTypes.number,
    optionalObject: React.PropTypes.object,
    optionalString: React.PropTypes.string,

    // 可以被渲染的對象 numbers, strings, elements 或 array
    optionalNode: React.PropTypes.node,

    //  React 元素
    optionalElement: React.PropTypes.element,

    // 用 JS 的 instanceof 操作符聲明 prop 為類的實例。
    optionalMessage: React.PropTypes.instanceOf(Message),

    // 用 enum 來限制 prop 只接受指定的值。
    optionalEnum: React.PropTypes.oneOf(['News', 'Photos']),

    // 可以是多個對象類型中的一個
    optionalUnion: React.PropTypes.oneOfType([
      React.PropTypes.string,
      React.PropTypes.number,
      React.PropTypes.instanceOf(Message)
    ]),

    // 指定類型組成的數(shù)組
    optionalArrayOf: React.PropTypes.arrayOf(React.PropTypes.number),

    // 指定類型的屬性構(gòu)成的對象
    optionalObjectOf: React.PropTypes.objectOf(React.PropTypes.number),

    // 特定 shape 參數(shù)的對象
    optionalObjectWithShape: React.PropTypes.shape({
      color: React.PropTypes.string,
      fontSize: React.PropTypes.number
    }),

    // 任意類型加上 `isRequired` 來使 prop 不可空。
    requiredFunc: React.PropTypes.func.isRequired,

    // 不可空的任意類型
    requiredAny: React.PropTypes.any.isRequired,

    // 自定義驗證器。如果驗證失敗需要返回一個 Error 對象。不要直接使用 `console.warn` 或拋異常,因為這樣 `oneOfType` 會失效。
    customProp: function(props, propName, componentName) {
      if (!/matchme/.test(props[propName])) {
        return new Error('Validation failed!');
      }
    }
  },
  /* ... */
});

六、React 組件 API

  • 設(shè)置狀態(tài):setState

  • 替換狀態(tài):replaceState

  • 設(shè)置屬性setProps

  • 替換屬性replaceProps

  • 強制更新:forceUpdate

  • 獲取DOM節(jié)點:findDOMNode

  • 判斷組件掛載狀態(tài):isMounted

    這里列舉兩例:setState 和 setProps,其它 API 使用大同小異,這里不一一例舉:
    
//setState
var Sta = React.createClass({
    getInitialState:function () {
        return {
            clickCount:0
        }
    },

//            clickEvent:function () {
//                this.setState({clickCount:this.state.clickCount+1})
//            },
//這里兩個 clickEvent 方法作用相同
    clickEvent:function () {
        this.setState(function (state) {
            return {clickCount:state.clickCount+1}
        })
    },

    render:function () {
        return <h1 onClick={this.clickEvent}>點擊的次數(shù)為:{this.state.clickCount}</h1>
    }

});

ReactDOM.render(
        <Sta/>,
        document.getElementById("example1")
);

//setProps
var Sprop = React.createClass({
    getInitialProps:function () {
        return {
            clickCount:0
        }
    },

    clickEvent:function () {
        this.setProps({clickCount:this.props.clickCount+1})
    },
//這里兩個 clickEvent 方法作用相同
//            clickEvent:function () {
//                this.setProps(function (state) {
//                    return {clickCount:state.clickCount+1}
//                })
//            },

    render:function () {
        return <h1 onClick={this.clickEvent}>點擊的次數(shù)為:{this.props.clickCount}</h1>
    }

});

ReactDOM.render(
        <Sta/>,
        document.getElementById("example2")
)

七、生命周期函數(shù)

  • 生命周期的方法有:
    • componentWillMount 在渲染前調(diào)用,在客戶端也在服務(wù)端。
    • componentDidMount : 在第一次渲染后調(diào)用,只在客戶端。之后組件已經(jīng)生成了對應(yīng)的DOM結(jié)構(gòu),可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中調(diào)用setTimeout, setInterval或者發(fā)送AJAX請求等操作(防止異部操作阻塞UI)。
    • componentWillReceiveProps 在組件接收到一個新的prop時被調(diào)用。這個方法在初始化render時不會被調(diào)用。
    • shouldComponentUpdate 返回一個布爾值。在組件接收到新的props或者state時被調(diào)用。在初始化時或者使用forceUpdate時不被調(diào)用。 可以在你確認不需要更新組件時使用。
    • componentWillUpdate在組件接收到新的props或者state但還沒有render時被調(diào)用。在初始化時不會被調(diào)用。
    • componentDidUpdate 在組件完成更新后立即調(diào)用。在初始化時不會被調(diào)用。
    • componentWillUnmount在組件從 DOM 中移除的時候立刻被調(diào)用。
<body>
    <div id="em1"></div>
    <div id="em2"></div>

    <script type="text/babel">
        //定義一個 Hello 組件,并且每秒鐘重新渲染一次
        var Hello = React.createClass({
            //初始化 state
            getInitialState:function () {
                return {opacity:1.0}
            },

            componentDidMount:function () {
                this.timer = setInterval(function () {
                    var opacity = this.state.opacity;
                    opacity -= 0.2;
                    if (opacity < 0.1){
                        opacity = 1.0;
                    }
                    this.setState({opacity:opacity})
                }.bind(this),1000);
            },

            render:function () {
                return (
                        <div style={{opacity:this.state.opacity}}>
                            Hello {this.props.name}
                        </div>
                )
            }
        });

        ReactDOM.render(
                <Hello name="Yijiang"/>,
                document.getElementById("em1")
        );

        //定義一個 Button 組件
        var Button = React.createClass({
            getInitialState:function () {
                return {data:0}
            },
            setNewNumber:function () {
                this.setState({data:this.state.data+1})
            },
            render:function () {
                return (
                        <div>
                            <button onClick={this.setNewNumber}>Increment</button>
                            <Content myNumber={this.state.data}></Content>
                        </div>
                )
            }
        });

        //定義一個 Content 組件
        var Content = React.createClass({
            componentWillMount:function () {
                console.log("component Will Mount");
            },
            componentDidMount:function () {
                console.log("component Did Mount");
            },
            componentWillReceiveProps:function(newProps) {
                console.log('Component WILL RECIEVE PROPS!')
            },
            shouldComponentUpdate:function(newProps, newState) {
                return true;
            },
            componentWillUpdate:function(nextProps, nextState) {
                console.log('Component WILL UPDATE!');
            },
            componentDidUpdate:function(prevProps, prevState) {
                console.log('Component DID UPDATE!')
            },
            componentWillUnmount:function() {
                console.log('Component WILL UNMOUNT!')
            },

            render: function () {
                return (
                        <div>
                            <h3>{this.props.myNumber}</h3>
                        </div>
                );
            }
        });
        ReactDOM.render(
                <div>
                    <Button />
                </div>,
                document.getElementById('em2')
        );

        /**
         * 首先會展示前兩條:
         * component Will Mount
         * component Did Mount
         * 當(dāng)點擊之后會顯示以下三條
         * Component WILL RECIEVE PROPS!
         * Component WILL UPDATE!
         * Component DID UPDATE!
         */
    </script>
</body>

八、React AJAX:

  • React 組件的數(shù)據(jù)可以通過 componentDidMount 方法中的 Ajax 來獲取,當(dāng)從服務(wù)端獲取數(shù)據(jù)庫可以將數(shù)據(jù)存儲在 state 中,再用 this.setState 方法重新渲染 UI。
  • 當(dāng)使用異步加載數(shù)據(jù)時,在組件卸載前,在 componentWillUnmount 里面取消未完成的請求。
var UserGist = React.createClass({
    getInitialState: function() {
        return {
            username: '',
            lastGistUrl: ''
        };
    },

    componentDidMount: function() {
        this.serverRequest = $.get(this.props.source, function (result) {
            var lastGist = result[0];
            this.setState({
                username: lastGist.owner.login,
                lastGistUrl: lastGist.html_url
            });
        }.bind(this));
    },

    componentWillUnmount: function() {
        this.serverRequest.abort();
    },

    render: function() {
        return (
                <div>
                    {this.state.username} 用戶最新的 Gist 共享地址:
                    <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a>
                </div>
        );
    }
});

ReactDOM.render(
        <UserGist source="https://api.github.com/users/octocat/gists" />,
        document.getElementById("em1")
);

九、React 表單與事件:

<body>
    <div id="em1"></div>
    <div id="em2"></div>
    <div id="em3"></div>
    <div id="em4"></div>
    <script type="text/babel">
        //一、React 表單與事件
        //設(shè)置輸入框 input 值value = {this.state.data}。在輸入框值發(fā)生變化時我們可以更新 state。
        var Yjw_input = React.createClass({
            getInitialState:function () {
                return {value:"Yijiangwang"}
            },
            changeValue:function (event) {
                this.setState({value:event.target.value})
            },
            render:function () {
                var txt = this.state.value;
                return (
                        <div>
                            <h3>這里是value的值:{this.state.value}</h3>
                            <input value={this.state.value} onChange={this.changeValue}/>
                        </div>
                )
            }
        });

        ReactDOM.render(
                <Yjw_input></Yjw_input>,
                document.getElementById("em1")
        );

        //在子組件上使用表單。 onChange 方法將觸發(fā) state 的更新并將更新的值傳遞到子組件的輸入框的 value 上來重新渲染界面。
        //在父組件通過創(chuàng)建事件句柄 (handleChange) ,并作為 prop (updateStateProp,這里名字可以隨意取) 傳遞到你的子組件上。
        //創(chuàng)建一個子組件
        var Content = React.createClass({
            render:function () {
                return  <div>
                    <h4>{this.props.myDataProp}</h4>
                    <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} />
                </div>;
            }
        });
        //創(chuàng)建一個父組件
        var HelloMessage = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: event.target.value});
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <Content myDataProp = {value}
                             updateStateProp = {this.handleChange}></Content>
                </div>;
            }
        });
        ReactDOM.render(
                <HelloMessage />,
                document.getElementById('em2')
        );

        //二、React 事件
        //通過 onClick 事件來修改數(shù)據(jù)
        var Yjw_click = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: 'Hello YijiangWang!'})
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <button onClick={this.handleChange}>點我</button>
                    <h4>{value}</h4>
                </div>;
            }
        });
        ReactDOM.render(
                <Yjw_click />,
                document.getElementById('em3')
        );

        //當(dāng)需要從子組件中更新父組件的 state 時,需要在父組件通過創(chuàng)建事件句柄 (handleChange) ,并作為 prop (updateStateProp) 傳遞到子組件上。
        //子組件
        var Child_event = React.createClass({
            render: function() {
                return  <div>
                    <button onClick = {this.props.updateStateProp}>點我</button>
                    <h4>{this.props.myDataProp}</h4>
                </div>
            }
        });
        //父組件
        var Father_event = React.createClass({
            getInitialState: function() {
                return {value: 'Hello Yijiang!'};
            },
            handleChange: function(event) {
                this.setState({value: 'Hello YijiangWang!'})
            },
            render: function() {
                var value = this.state.value;
                return <div>
                    <Child_event myDataProp = {value}
                             updateStateProp = {this.handleChange}></Child_event>
                </div>;
            }
        });
        ReactDOM.render(
                <Father_event />,
                document.getElementById('em4')
        );
    </script>
</body>

十、React Refs

  • React 支持一種非常特殊的屬性 Ref ,你可以用來綁定到 render() 輸出的任何組件上。
  • 這個特殊的屬性允許你引用 render() 返回的相應(yīng)的支撐實例( backing instance )。這樣就可以確保在任何時間總是拿到正確的實例。
  • 使用方法:
//綁定一個 ref 屬性到 render 的返回值上:
<input ref="myInput" />
//在其它代碼中,通過 this.refs 獲取支撐實例:
var input = this.refs.myInput;
var inputValue = input.value;
var inputRect = input.getBoundingClientRect();
  • 具體實例:
<div id="em1"></div>
<script type="text/babel">
    //可以通過使用 this 來獲取當(dāng)前 React 組件,或使用 ref 來獲取組件的引用
    var Yjw_component = React.createClass({
                handleClick: function() {
                    // 使用原生的 DOM API 獲取焦點
                    this.refs.myInput.focus();
                },
                render: function() {
                    //  當(dāng)組件插入到 DOM 后,ref 屬性添加一個組件的引用于到 this.refs
                    return (
                            <div>
                                <input type="text" ref="myInput" />
                                <input
                                        type="button"
                                        value="點我輸入框獲取焦點"
                                        onClick={this.handleClick}
                                />
                            </div>
                    );
                }
            });

    ReactDOM.render(
            <Yjw_component />,
            document.getElementById('em1')
    );
</script>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 3. JSX JSX是對JavaScript語言的一個擴展語法, 用于生產(chǎn)React“元素”,建議在描述UI的時候...
    pixels閱讀 2,979評論 0 24
  • HTML模版 之后出現(xiàn)的React代碼嵌套入模版中。 1. Hello world 這段代碼將一個一級標(biāo)題插入到指...
    ryanho84閱讀 6,445評論 0 9
  • 原教程內(nèi)容詳見精益 React 學(xué)習(xí)指南,這只是我在學(xué)習(xí)過程中的一些閱讀筆記,個人覺得該教程講解深入淺出,比目前大...
    leonaxiong閱讀 2,944評論 1 18
  • 本筆記基于React官方文檔,當(dāng)前React版本號為15.4.0。 1. 安裝 1.1 嘗試 開始之前可以先去co...
    Awey閱讀 7,932評論 14 128
  • 深入JSX date:20170412筆記原文其實JSX是React.createElement(componen...
    gaoer1938閱讀 8,183評論 2 35

友情鏈接更多精彩內(nèi)容