1. 程式人生 > >react官網學習筆記

react官網學習筆記

學習地址:https://react.docschina.org/

http://www.runoob.com/react/react-tutorial.html

1.react第一個例項:Hello, world!

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Hello React!</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>

<div id="example"></div>
<script type="text/babel">
ReactDOM.render(
	<h1>Hello, world!</h1>,
	document.getElementById('example')
);
</script>

</body>
</html>

2.React 安裝

本教程使用了 React 的版本為 16.4.0,你可以在官網 https://reactjs.org/ 下載最新版。

你也可以直接使用 Staticfile CDN 的 React CDN 庫,地址如下:

<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生產環境中不建議使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>

官方提供的 CDN 地址:

<script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
<script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
<!-- 生產環境中不建議使用 -->
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>

將這三個地址寫到<head></head>標籤內

3.元素渲染

    <!-- 我們用react開發應用時一般只會定義一個根節點,此處定義一個id為example的div -->
    <div id="example"></div>
    <script type="text/babel">
        //元素式構成React應用的最小單位,用於描述螢幕上輸出的內容
        const element = <h1>Hello, world!</h1>;
        //要將React元素渲染到根節點中,用ReactDOM.render()方法
        ReactDOM.render(
            element,
            document.getElementById('example')
        );
    </script>

4.更新元素渲染

    <div id="example"></div>
    <script type="text/babel">
        //更新元素渲染:React元素都是不可變的。當元素被建立之後,無法改變內容或屬性。只能建立一個新的元素
        // toLocaleTimeString() 方法返回該日期物件時間部分的字串
        function tick(){
            const element = (
                <div>
                    <h1>Hello, world!</h1>
                    <h2>現在是{new Date().toLocaleTimeString()}.</h2>
                </div>
            );
            ReactDOM.render(
                element,
                document.getElementById('example')
            );
        }
        setInterval(tick,1000);//通過 setInterval() 方法,每秒鐘呼叫一次 ReactDOM.render()。

5.將要展示的部分封裝起來

        function Clock(props){
            return(
                <div>
                    <h1>封裝起來</h1>
                    <h2>現在是{props.date.toLocaleTimeString()}.</h2>
                </div>
            );
        }
        function tick(){
            ReactDOM.render(
                <Clock date={new Date()}/>,
                document.getElementById("example")
            );
        }
        setInterval(tick,1000);

6.建立React.Component的類,需要注意的是在 render() 方法中,需要使用 this.props 替換 props:

        class Clock extends React.Component{
            render(){
                return(
                    <div>
                        <h1>建立一個類</h1>
                        <h2>現在是{this.props.date.toLocaleTimeString()}.</h2>
                    </div>
                );
            }
        }
        function tick(){
            ReactDOM.render(
                <Clock date = {new Date()} />,
                document.getElementById("example")
            );
        }
        setInterval(tick,1000);

7.React JSX

React使用JSX來替代常規的javascript

例項中的 p 元素添加了自定義屬性 data-myattribute,新增自定義屬性需要使用 data- 字首。

    <div id="example"></div>
    <script type="text/babel">
        ReactDOM.render(
            <div>
                <h1>React JSX</h1>
                <p data-myattribute="somevalue">例項中的 p 元素添加了自定義屬性 data-myattribute,新增自定義屬性需要使用 data- 字首。</p>
            </div>
            ,
            document.getElementById("example")
        );
    </script>

8.React JSX 程式碼可以放在一個獨立檔案上,例如我們建立一個 helloworld_react.js 檔案

ReactDOM.render(
  <h1>Hello, world!</h1>,
  document.getElementById('example')
);
<body>
  <div id="example"></div>
  <script type="text/babel" src="./helloworld_react.js"></script>
</body>

9.JSX中使用javascript表示式,表示式寫在{}中

在JSX中不能使用if else語句,但可以使用conditional(三元運算)表示式來替代

    <script type="text/babel">
        var i=1;
        ReactDOM.render(
            <div>
                <h1>{i==1?"True!":"False"}</h1>
            </div>
            ,
            document.getElementById("example")
        )
    </script>

10.樣式

        var myStyle={
            fontSize:100,
            color:"#FF0000"
        };
        ReactDOM.render(
            <h1 style = {myStyle}>樣式</h1>,
            document.getElementById("example")
        )

11.註釋

註釋需要寫在一對花括號中

        ReactDOM.render(
            <div>
                <h1>註釋</h1>
                {/* 註釋需要寫在一對花括號中 */}
            </div>,
            document.getElementById("example")
        )

12.陣列

JSX允許再模板中插入陣列,陣列會自動展開所有成員:

        var arr = [1,2];
        ReactDOM.render(
            <div>{arr}</div>,
            document.getElementById("example")
        );

13.HTML標籤vs.React元件

要渲染HTML標籤,只需在JSX裡使用小寫字母的標籤名:

    <script type="text/babel">
        var myDivElement = <div className="foo" />;
        ReactDOM.render(myDivElement,document.getElementById("example"));
    </script>

 

14.React元件

    <script type="text/babel">
        function HelloMessage(props){
            return <h1>元件</h1>;
        }
        const element = <HelloMessage />;
        ReactDOM.render(element,document.getElementById("example"));
    </script>

向元件傳值

        function HelloMessage(props){
            return <h1>元件{props.name}!</h1>;
        }
        const element = <HelloMessage name="Alisa" />;
        ReactDOM.render(element,document.getElementById("example"));

複合元件

    <script type="text/babel">
        function Name(props){
            return <h1>姓名:{props.name}</h1>;
        }
        function Sex(props){
            return <h1>性別:{props.sex}</h1>;
        }
        function Age(props){
            return <h1>年齡:{props.age}</h1>;
        }
        function Study(){
            return(
                <div>
                    <Name name="Alisa" />
                    <Sex sex="女" />
                    <Age age="23" />
                </div>
            )
        }
        ReactDOM.render(
            <Study />,
            document.getElementById("example")
        )
    </script>

15.React State(狀態)

建立一個名稱擴充套件為React.Component的ES6類,在render()方法中使用this.state來修改當前的時間

新增一個類建構函式來初始化狀態this.state,類元件應始終使用props呼叫基礎建構函式

    <script type="text/babel">
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            render(){
                return(
                    <div>
                        <h1>在render()方法中使用this.state來修改當前的時間</h1>
                        <h2>現在是{this.state.date.toLocaleTimeString()}.</h2>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

16.將生命週期方法新增到類中

componentDidMount() 與 componentWillUnmount() 方法被稱作生命週期鉤子。

在元件輸出到 DOM 後會執行 componentDidMount() 鉤子,我們就可以在這個鉤子上設定一個定時器。

this.timerID 為計算器的 ID,我們可以在 componentWillUnmount() 鉤子中解除安裝計算器。

    <script type="text/babel">
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID = setInterval(
                    ()=> this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return (
                    <div>
                        <h1>生成/移除定時器</h1>
                        <h2>現在是{this.state.date.toLocaleTimeString()}.</h2>
                    </div>
                );
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

17.資料自頂向下流動

    <script type="text/babel">
        function FormattedDate(props){
            return <h2>現在是{props.date.toLocaleTimeString()}.</h2>
        }
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID=setInterval(
                    ()=>this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return(
                    <div>
                        <h1>例項中 FormattedDate 元件將在其屬性中接收到 date 值,並且不知道它是來自 Clock 狀態、還是來自 Clock 的屬性、亦或手工輸入</h1>
                        <FormattedDate date={this.state.date} />
                    </div>
                );
            }
        }
        ReactDOM.render(
            <Clock />,
            document.getElementById("example")
        );
    </script>

所有元件都是真正隔離的

    <script type="text/babel">
        function FormattedDate(props){
            return <h2>現在是{props.date.toLocaleTimeString()}.</h2>;
        }
        class Clock extends React.Component{
            constructor(props){
                super(props);
                this.state={date:new Date()};
            }
            componentDidMount(){
                this.timerID=setInterval(
                    ()=>this.tick(),
                    1000
                );
            }
            componentWillUnmount(){
                clearInterval(this.timerID);
            }
            tick(){
                this.setState({
                    date:new Date()
                });
            }
            render(){
                return (
                    <div>
                        <h1>為了表明所有元件都是真正隔離的,我們可以建立一個 App 元件,它渲染三個Clock:</h1>
                        <FormattedDate date={this.state.date} />
                    </div>
                );
            }
        }
        function App(){
            return(
                <div>
                    <Clock />
                    <Clock />
                    <Clock />
                </div>
            )
        }
        ReactDOM.render(
            <App />,
            document.getElementById("example")
        )
    </script>

18.Props

使用props

    <script type="text/babel">
        function HelloMessage(props){
            return <h1>Hello{props.name}!</h1>
        }
        const element = <HelloMessage name="Alisa" />;
        ReactDOM.render(
            element,document.getElementById("example")
        );
    </script>

預設props

    <script type="text/babel">
        class HelloMessage extends React.Component{
            render(){
                return (
                    <h1>Hello,{this.props.name}</h1>
                );
            }
        }
        HelloMessage.defaultProps = {
            name:"Alisa"
        };
        const element = <HelloMessage />;
        ReactDOM.render(
            element,document.getElementById("example")
        );
    </script>

state和Props

我們可以在父元件中設定state,並通過在子元件上使用props將其傳遞到子元件上

    <script type="text/babel">
    class Website extends React.Component{
        constructor(){
            super();
            this.state={
                name:"Alisa",
                sex:"女"
            }
        }
        render(){
            return (
                <div>
                    <Name name={this.state.name} />
                    <Sex sex={this.state.sex} />
                </div>
            )
        }
    }
    class Name extends React.Component{
        render(){
            return (
                <h1>{this.props.name}</h1>
            );
        }
    }
    class Sex extends React.Component{
        render(){
            return(
                <a href={this.props.sex}>{this.props.sex}</a>
            );
        }
    }
    ReactDOM.render(
        <Website />,document.getElementById("example")
    );
    </script>

19.Props驗證

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://unpkg.com/[email protected]/umd/react.development.js"></script>
    <script src="https://unpkg.com/[email protected]/umd/react-dom.development.js"></script>
    <!-- 生產環境中不建議使用 -->
    <script src="https://unpkg.com/[email protected]/babel.min.js"></script>
    <!-- Props驗證必須要下面這個js連結 -->
    <script src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- Props -->
    <!-- Props驗證 -->
    <script type="text/babel">
        var title="Alisa";//如果此處var title=123,控制器那裡會報錯,顯示資料型別錯誤
        class MyTitle extends React.Component{
            render(){
                return (
                    <h1>Hello ,{this.props.title}</h1>
                );
            }
        }
        MyTitle.propTypes={
            title:PropTypes.string
        };
        ReactDOM.render(
            <MyTitle title={title} />,document.getElementById("example")
        )
    </script>
</body>
</html>
<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.staticfile.org/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.staticfile.org/babel-standalone/6.22.1/babel.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- Props -->
    <!-- Props驗證 -->
    <!-- Props 驗證使用 propTypes,它可以保證我們的應用元件被正確使用,React.PropTypes 提供很多驗證器 (validator) 來驗證傳入資料是否有效。當向 props 傳入無效資料時,JavaScript 控制檯會丟擲警告。 -->
    <!-- 建立一個 Mytitle 元件,屬性 title 是必須的且是字串,非字串型別會自動轉換為字串 : -->
    <script type="text/babel">
        var title="Alisa";//如果此處var title=123,控制器那裡會報錯,顯示資料型別錯誤
        var MyTitle = React.createClass({
            propTypes:{
                title:React.PropTypes.string.isRequired,
            },
            render:function(){
                return <h1>{this.props.title}</h1>;
            }
        });
        ReactDOM.render(
            <MyTitle title={title} />,
            document.getElementById("example")
        );
    </script>
</body>
</html>

更多驗證器說明:

        MyComponent.propTypes = {
            //可以宣告prop為指定的js基本資料型別,預設情況,這些資料是可選的
            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)
            ]),
            //指定型別組成的陣列
            optionalArrayOf:React.PropTypes.arrayOf(React.PropTypes.number),
            //指定型別的屬性構成的物件
            optionalObjectOf:React.PropTypes.objectOf(React.PropTypes.number),
            //特定shape引數的物件
            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("Validationfailed!");
                }
            }
        }

20.React 事件處理

React 元素的事件處理和 DOM 元素類似。但是有一點語法上的不同:

React 事件繫結屬性的命名採用駝峰式寫法,而不是小寫。

如果採用 JSX 的語法你需要傳入一個函式作為事件處理函式,而不是一個字串(DOM 元素的寫法)

        class Toggle extends React.Component{
            constructor(props){
                super(props);
                this.state={isToggleOn:true};
                //這邊繫結是必要的,這樣'this'才能在回撥函式中使用
                this.handleClick=this.handleClick.bind(this);
            }
            handleClick(){
                this.setState(prevState=>({
                    isToggleOn:!prevState.isToggleOn
                }));
            }
            render(){
                return(
                    <button onClick={this.handleClick}>{this.state.isToggleOn ? "ON":"OFF"}
                    </button>
                );
            }
        }
        ReactDOM.render(
            <Toggle />,
            document.getElementById("example")
        );

使用屬性初始化器來正確的繫結回撥函式:

    <script type="text/babel">
        class LoggingButton extends React.Component{
            //這個語法確保了"this"繫結在handleClick
            handClick=()=>{
                console.log("this is:",this);
            }
            render(){
                return (
                    <button onClick={this.handClick}>Click me</button>
                )
            }
        }
        ReactDOM.render(
            <LoggingButton />,
            document.getElementById("example")
        );
    </script>

在回撥函式中使用 箭頭函式:

    <script type="text/babel">
        class LoggingButton extends React.Component{
            handleClick(){
                console.log("this is:",this);
            }
            render(){
                //這個語法確保了'this'繫結在handleClick中
                return(
                    <button onClick={(e)=>this.handleClick(e)}>Click me</button>
                )
            }
        }
        ReactDOM.render(
            <LoggingButton />,
            document.getElementById("example")
        );
    </script>

21.向事件處理程式傳遞引數

若是 id 是你要刪除那一行的 id,以下兩種方式都可以向事件處理程式傳遞引數:

<button onClick={(e)=>this.deleteRow(id,e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this,id)}>Delete Row</button>

通過 bind 方式向監聽函式傳參,在類元件中定義的監聽函式,事件物件 e 要排在所傳遞引數的後面

    <script type="text/babel">
        class Popper extends React.Component{
            constructor(){
                super();
                this.state = {name:"Hello World!"};
            }
            preventPop(name,e){//事件物件e要放在最後
                e.preventDefault();
                alert(name);
            }
            render(){
                return(
                    <div>
                    <p>hello</p>
                    {/* 通過bind()方法傳遞引數。 */}
                    <a href="https://reactjs.org" onClick={this.preventPop.bind(this,this.state.name)}>Click</a>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Popper />,
            document.getElementById("example")
        );
    </script>

22.React 條件渲染

    <script type="text/babel">
        function UserGreeting(props){
            return <h1>歡迎回來!</h1>;
        }
        function GuestGreeting(props){
            return <h1>請先註冊!</h1>;
        }
        function Greeting(props){
            const isLoggedIn = props.isLoggedIn;
            if(isLoggedIn){
                return <UserGreeting />
            }
            return <GuestGreeting />
        }
        ReactDOM.render(
            //嘗試修改isLoggedIn={true}
            <Greeting isLoggedIn={false} />,
            document.getElementById("example")
        );
    </script>

23.元素變數

    <script type="text/babel">
        function LoginButton(props){
            return (
                <button onClick={props.onClick}>登入</button>
            );
        }
        function LogoutButton(props){
            return (
                <button onClick={props.onClick}>退出</button>
            )
        }
        function UserGreeting(props){
            return <h1>歡迎回來!</h1>;
        }
        function GuestGreeting(props){
            return <h1>請先註冊!</h1>;
        }
        function Greeting(props){
            const isLoggedIn=props.isLoggedIn;
            if(isLoggedIn){
                return <UserGreeting />;
            }
            return <GuestGreeting />;
        }
        class LoginControl extends React.Component{
            constructor(props){
                super(props);
                this.handleLoginClick= this.handleLoginClick.bind(this);
                this.handleLogoutClick=this.handleLogoutClick.bind(this);
                this.state={isLoggedIn:false};
            }
            handleLoginClick(){
                this.setState({isLoggedIn:true});
            }
            handleLogoutClick(){
                this.setState({isLoggedIn:false});
            }
            render(){
                const isLoggedIn=this.state.isLoggedIn;
                let button = null;
                if(isLoggedIn){
                    button=<LogoutButton onClick={this.handleLogoutClick} />;
                }else{
                    button=<LoginButton onClick={this.handleLoginClick} />;
                }
                return (
                    <div>
                        <Greeting isLoggedIn={isLoggedIn} />
                        {button}
                    </div>
                )
            }
        }
        ReactDOM.render(
            <LoginControls/>,
            document.getElementById("example")
        )
    </script>

24.與運算子&&

    <script type="text/babel">
        function Mailbox(props){
            const unreadMessages = props.unreadMessages;
            return (
                <div>
                    <h1>Hello!</h1>
                    {unreadMessages.length>0 &&
                        <h2>您有{unreadMessages.length}條未讀資訊。</h2>
                    }
                </div>
            );
        }
        const messages = ["Alisa","Hello","World","Happy"];
        ReactDOM.render(
            <Mailbox unreadMessages={messages} />,
            document.getElementById("example")
        );
    </script>

25.阻止元件渲染

    <script type="text/babel">
        function WarningBanner(props){
            if(!props.warn){
                return null;
            }
            return (
                <div className="warning">警告!</div>
            );
        }
        class Page extends React.Component{
            constructor(props){
                super(props);
                this.state = {showWarning:true}
                this.handleToggleClick = this.handleToggleClick.bind(this);
            }
            handleToggleClick(){
                this.setState(prevState=>({
                    showWarning:!prevState.showWarning
                }));
            }
            render(){
                return (
                    <div>
                        <WarningBanner warn={this.state.showWarning}/>
                        <button onClick={this.handleToggleClick}>
                            {this.state.showWarning ? "隱藏":"顯示"}
                        </button>
                    </div>
                )
            }
        }
        ReactDOM.render(
            <Page />,
            document.getElementById("example")
        )
    </script>

26.React 列表 & Keys

使用 map() 方法遍歷陣列生成了一個 1 到 5 的數字列表:

    <script type="text/babel">
        const numbers = [1,2,3,4,5];
        const listItems = numbers.map((numbers)=>
            <li>{numbers}</li>
        );
        ReactDOM.render(
            <ul>{listItems}</ul>,
            document.getElementById("example")
        );
    </script>

27.將以上例項重構成一個元件,元件接收陣列引數,每個列表元素分配一個 key

    <script type="text/babel">
        function NumberList(props){
            const numbers = props.numbers;
            const listItems = numbers.map((number)=>
                <li key={number.toString()}>{number}</li>
            );
            return (
                <ul>{listItems}</ul>
            );
        }
        const numbers=[1,2,3,4,5];
        ReactDOM.render(
            <NumberList numbers={numbers} />,
            document.getElementById("example")
        );
    </script>

用key提取元件

    <script type="text/babel">
        function ListItem(props){
            //這裡不需要指定Key:
            return <li>{props.value}</li>
        }
        function NumberList(props){
            const numbers = props.numbers;
            const listItems = numbers.map((number)=>
                //key應該在陣列的上下文中被指定
                <ListItem key={number.toString()} value={number} />
            );
            return (
                <ul>{listItems}</ul>
            );
        }
        const numbers = [1,2,3,4,5];
        ReactDOM.render(
            <NumberList numbers={numbers} />,
            document.getElementById("example")
        )
    </script>

元素的 key 在他的兄弟元素之間應該唯一

    <script type="text/babel">
        function Blog(props){
            const sidebar = (
                <ul>
                    {props.posts.map((post)=>
                        <li key={post.id}>{post.title}</li>
                    )}
                </ul>
            );
            const content = props.posts.map((post)=>
                <div key={post.id}>
                    <h3>{post.title}</h3>
                    <p>{post.content}</p>
                </div>
            );
            return (
                <div>
                {sidebar}
                <hr/>
                {content}
                </div>
            );
        }
        const posts = [
            {id:1,title:"Hello World",content:"Welcome"},
            {id:2,title:"World!",content:"All"}
        ];
        ReactDOM.render(
            <Blog posts = {posts} />,
            document.getElementById("example")
        )
    </script>

28.React 元件 API

設定狀態:setState

setState(object nextState[, function callback])

nextState,將要設定的新狀態,該狀態會和當前的state合併

callback,可選引數,回撥函式。該函式會在setState設定成功,且元件重新渲染後呼叫。

合併nextState和當前state,並重新渲染元件。setState是React事件處理函式中和請求回撥函式中觸發UI更新的主要方法。

    <script type="text/babel">
        class Counter extends React.Component{
            constructor(props){
                super(props);
                this.state = {clickCount:0};
                this.handleClick = this.handleClick.bind(this);
            }
            handleClick(){
                this.setState(function(state){
                    return {clickCount:state.clickCount+1};
                });
            }
            render(){
                return (
                    <h2 onClick={this.handleClick}>
                    點我!點選次數為:{this.state.clickCount}
                    </h2>
                );
            }
        }
        ReactDOM.render(
            <Counter />,
            document.getElementById("example")
        );
    </script>

替換狀態:replaceState

replaceState(object nextState[, function callback])

nextState,將要設定的新狀態,該狀態會替換當前的state。

callback,可選引數,回撥函式。該函式會在replaceState設定成功,且元件重新渲染後呼叫。

replaceState()方法與setState()類似,但是方法只會保留nextState中狀態,原state不在nextState中的狀態都會被刪除。

 

設定屬性:setProps
setProps(object nextProps[, function callback])
nextProps,將要設定的新屬性,該狀態會和當前的props合併
callback,可選引數,回撥函式。該函式會在setProps設定成功,且元件重新渲染後呼叫。
設定元件屬性,並重新渲染元件。

 

替換屬性:replaceProps
replaceProps(object nextProps[, function callback])
nextProps,將要設定的新屬性,該屬性會替換當前的props。
callback,可選引數,回撥函式。該函式會在replaceProps設定成功,且元件重新渲染後呼叫。
replaceProps()方法與setProps類似,但它會刪除原有 props。

 

強制更新:forceUpdate
forceUpdate([function callback])
引數說明
callback,可選引數,回撥函式。該函式會在元件render()方法呼叫後呼叫。
forceUpdate()方法會使元件呼叫自身的render()方法重新渲染元件,元件的子元件也會呼叫自己的render()。但是,元件重新渲染時,依然會讀取this.props和this.state,如果狀態沒有改變,那麼React只會更新DOM。

forceUpdate()方法適用於this.props和this.state之外的元件重繪(如:修改了this.state後),通過該方法通知React需要呼叫render()

一般來說,應該儘量避免使用forceUpdate(),而僅從this.props和this.state中讀取狀態並由React觸發render()呼叫。
 

獲取DOM節點:findDOMNode
DOMElement findDOMNode()
返回值:DOM元素DOMElement
如果元件已經掛載到DOM中,該方法返回對應的本地瀏覽器 DOM 元素。當render返回null 或 false時,this.findDOMNode()也會返回null。從DOM 中讀取值的時候,該方法很有用,如:獲取表單欄位的值和做一些 DOM 操作。

 

判斷元件掛載狀態:isMounted
bool isMounted()
返回值:true或false,表示元件是否已掛載到DOM中
isMounted()方法用於判斷元件是否已掛載到DOM中。可以使用該方法保證了setState()和forceUpdate()在非同步場景下的呼叫不會出錯。

29.React 元件生命週期

元件的生命週期可分成三個狀態:

Mounting:已插入真實 DOM
Updating:正在被重新渲染
Unmounting:已移出真實 DOM
生命週期的方法有:

componentWillMount 在渲染前呼叫,在客戶端也在服務端。

componentDidMount : 在第一次渲染後呼叫,只在客戶端。之後元件已經生成了對應的DOM結構,可以通過this.getDOMNode()來進行訪問。 如果你想和其他JavaScript框架一起使用,可以在這個方法中呼叫setTimeout, setInterval或者傳送AJAX請求等操作(防止非同步操作阻塞UI)。

componentWillReceiveProps 在元件接收到一個新的 prop (更新後)時被呼叫。這個方法在初始化render時不會被呼叫。

shouldComponentUpdate 返回一個布林值。在元件接收到新的props或者state時被呼叫。在初始化時或者使用forceUpdate時不被呼叫。 
可以在你確認不需要更新元件時使用。

componentWillUpdate在元件接收到新的props或者state但還沒有render時被呼叫。在初始化時不會被呼叫。

componentDidUpdate 在元件完成更新後立即呼叫。在初始化時不會被呼叫。

componentWillUnmount在元件從 DOM 中移除之前立刻被呼叫。

    <script type="text/babel">
        class Hello extends React.Component{
            constructor(props){
                super(props);
                this.state = {opacity:1.0};
            }
            componentDidMount(){
                this.timer = setInterval(function(){
                    var opacity = this.state.opacity;
                    opacity -= .05;
                    if(opacity <0.1){
                        opacity=1.0;
                    }
                    this.setState({
                        opacity:opacity
                    });
                }.bind(this),100);
            }
            render(){
                return (
                    <div style={{opacity:this.state.opacity}}>Hello{this.props.name}</div>
                );
            }
        }
        ReactDOM.render(
            <Hello name="world" />,
            document.body
        );
    </script>

以下例項初始化 state , setNewnumber 用於更新 state。所有生命週期在 Content 元件中。

    <script type="text/babel">
        class Button extends React.Component{
            constructor(props){
                super(props);
                this.state = {data:0};
                this.setNewNumber = this.setNewNumber.bind(this);
            }
            setNewNumber(){
                this.setState({data:this.state.data+1})
            }
            render(){
                return(
                    <div>
                        <button onClick={this.setNewNumber}>INCREMENT</button>
                        <Content myNumber = {this.state.data}></Content>
                    </div>
                );
            }
        }
        class Content extends React.Component{
            componentWillMount(){
                console.log("componentWillMount")
            }
            componentDidMount(){
                console.log("componentDidMount")
            }
            componentWillReceiveProps(newProps){
                console.log("componentWillReceiveProps")
            }
            shouldComponentUpdate(newProps,newState){
                return true;
            }
            componentWillUpdate(nextProps,nextState){
                console.log("componentWillUpdate")
            }
            componentDidUpdate(prevProps,prevState){
                console.log("componentDidUpdate")
            }
            render(){
                return(
                    <div><h3>{this.props.myNumber}</h3></div>
                );
            }
        }
        ReactDOM.render(
            <div><Button /></div>,
            document.getElementById("example")
        )
    </script>

30.React AJAX

<!DOCTYPE html>
<html lang="UTF-8">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Hello React!</title>
    <script src="https://cdn.staticfile.org/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.staticfile.org/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.staticfile.org/babel-standalone/6.22.1/babel.min.js"></script>
    <!-- 必須加下面這個連結,否則報錯$沒有定義 -->
    <script src="https://cdn.staticfile.org/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <div id="example"></div>
    <!-- React AJAX -->
    <script type="text/babel">
        class UserGist extends React.Component{
            constructor(props){
                super(props);
                this.state = {username:"",lastGistUrl:""};
            }
            componentDidMount(){
                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(){
                this.serverRequest.abort();
            }
            render(){
                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("example")
        )
    </script>
</body>
</html>

31.React 表單與事件

設定了輸入框 input 值 value = {this.state.data}。在輸入框值發生變化時我們可以更新 state。我們可以使用 onChange 事件來監聽 input 的變化,並修改 state。 

    <script type="text/babel">
        class HelloMessage extends React.Component{
            constructor(props){
                super(props);
                this.state={value:"Hello!"};
                this.handleChange = this.handleChange.bind(this);
            }
            handleChange(event){
                this.setState({value:event.target.value});
            }
            render(){
                var value = this.state.value;
                return <div>
                <input type="text" value={value} onChange={this.handleChange} />
                <h4>{value}</h4>
                </div>;
            }
        }
        ReactDOM.render(
            <HelloMessage />,
            document.getElementById("example")
        );
    </script>

32.React Refs

允許你引用 render() 返回的相應的支撐例項( backing instance )。這樣就可以確保在任何時間總是拿到正確的例項。

    <script type="text/babel">
        class MyComponent extends React.Component{
            handleClick(){
                //使用原生的DOM API獲取焦點
                this.refs.myInput.focus();
            }
            render(){
                //當元件插入到DOM後,ref屬性新增一個元件的引用於到this.refs
                return(
                    <div>
                        <input type="text" ref="myInput" />
                        <input type="button" value="點我輸入框獲取焦點" onClick={this.handleClick.bind(this)} />
                    </div>
                );
            }
        }
        ReactDOM.render(
            <MyComponent />,
            document.getElementById("example")
        )
    </script>

33.接下來是自己的一些小練習

  • 點選彈出文案
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <div className="App">
        <h1 className="abc" onClick={this.handleClick}>Hello, world!</h1>
      </div>
    );
  }
}

export default App;
  • 新建一個Content.js,同時,Content.js裡面的值是通過在開頭定義好,然後引入的。再將Content.js引入到App.js

App.js

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import Content from "./Content"

class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <Content />
    );
  }
}

export default App;

Content.js

import React, { Component } from 'react';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
      </div>
    );
  }
}
export default Con;
  • 將App.js內的一個類傳遞到另外一個類中
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
      </div>
    );
  }
}
class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <Con />
    );
  }
}

export default App;
  • 定義一個元件並傳值,可以通過function定義一個函式,也可以通過class定一個類來實現
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
const con = {
  h1text:"Hello",
  h2text:"world"
};
const h1style={
  color:"blue"
}
class Con extends Component {
  render() {
    return (
      <div className="App">
        <h1 style={h1style}>{con.h1text}</h1>
        <h2>{con.h2text}</h2>
        <button onClick={Welcome}>click me</button>
      </div>
    );
  }
}
function Welcome(props){
  return(
    console.log(123)
  )
}
class App extends Component {
  constructor(props){
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }
  handleClick(){
    alert("click")
  }
  render() {
    return (
      <div>
        <Con />
        <button onClick={this.handleClick}>click me</button>
      </div>
    );
  }
}

export default App;
  • 先在中端通過npm install prop-types --save下載prop-types,然後輸入程式碼,雖然會顯示內容,但是不符合型別的定義型別會在控制檯報錯
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import PropTypes from 'prop-types';
class Son extends React.Component{
  render(){
    return(
      <div style={{padding:30}}>
        {this.props.number}
        <hr/>
        {this.props.array}
        <hr/>
        {this.props.boolean.toString()}
      </div>
    )
  }
}
Son.propTypes = {
  number:PropTypes.number,
  array:PropTypes.array,
  boolean:PropTypes.bool
}
class Father extends React.Component{
  render(){
    return (
      <Son number = {1} array={"[1,2,3]"} boolean = {"true"}
       />
    )
  }
}
export default Father;