天天看點

React 入門執行個體教程

目錄

  1. html模闆
  2. ReactDOM.render()
  3. JSX 文法
  4. 元件 & props
  5. props & 純函數
  6. 事件
  7. 清單渲染
  8. 條件渲染
  9. this.state
  10. style和class
  11. 生命周期
  12. 表單
  13. 擷取真實的DOM節點
  14. this.props.children

一、html模闆

<!DOCTYPE html>
<html>
  <head>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    // script的類型必須是text/babel
    <script type="text/babel">
     // todo
    </script>
  </body>
</html>
           

二、ReactDOM.render()

作用: 編譯模闆,把模闆挂載到指定的節點上

<!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>Document</title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="app">

    </div>
</body>

</html>


<script type="text/babel">
    ReactDOM.render(
        <h1>hello world</h1>,
        document.getElementById('app')
    )
</script>
           

三、JSX 文法

說明: jsx文法html代碼和js代碼可以混寫而不需要加引号,可以這樣做的原因是React和到jsx代碼後會進行編譯,使代碼正确運作.當然jsx也是有它自己本身的規則:

  1. js代碼需要用{}括起來
  2. React編譯規則: 遇到<開頭就看作是html,遇到{開頭則視為js
<!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>Document</title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root"></div>
</body>

</html>

<script type="text/babel">
    const person = {
        name: 'huruqing',
        age: 108
    }; 
    const element = 
        <h1>
            <p>姓名: {person.name}</p>
            <p>年齡: {person.age}歲</p>
        </h1>;

        ReactDOM.render( 
            element, 
            document.getElementById('root')
        );
</script>
           

四、元件

  1. 用es5定義一個react元件
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">



    </div>
</body>

</html>

<script type="text/babel">
    // es5元件的寫法,一個函數就是一個元件
    function Welcome(props) {
      return (
            <h1>
                <p>姓名: {props.person.name}</p>
                <p>年齡: {props.person.age}</p>
            </h1>
        )
    }

    const person = {
        name: 'huruqing',
        age: 108
    }
    ReactDOM.render(
        <Welcome person={person} />,
        document.getElementById('root')
    )
</script>
           
  1. 用es6定義個react元件
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">


        <h1>
            <p>姓名: </p>
            <p>年齡: </p>
        </h1>
    </div>
</body>

</html>

<script type="text/babel">
    /**
        * es6使用class的形式來建立元件,繼承React的Component類,
        * 後面我們更多的使用這種方式來建立元件
     */ 
    class Welcome extends React.Component {
        constructor(props) {
            super(props);
        }
        render() {
            return (
                <h1>
                    <p>姓名: {this.props.person.name}</p>
                    <p>年齡: {this.props.person.age} </p>
                </h1>
            )
        }
    }

    const person = {
        name: 'huruqing',
        age: 108
    }
    ReactDOM.render(
        <Welcome person={person} />,
        document.getElementById('root')
    )
</script>
           

五、props和純函數

  1. 相同的輸入有相同的輸出,輸入可以确定輸出,這就是純函數
  2. 對待props就像對待純函數一樣,遵循可以通過輸入确定輸出
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="app">

    </div>
</body>

</html>

<script type="text/babel">
    // 這是個純函數,輸入什麼,得到什麼是一定的,同樣的輸入必定有同樣的輸出
    const sum = (a, b) => {
        return a + b; 
    }
    sum(2,3); // 5
    sum(2,3); // 5
    
    // 這個函數是不純的,因為它修改了外部傳進來的參數
    let count = 0;
    const getResult = (num) => {
        count++;
      return num*num + count;
    }
        getResult(2); // 5
        getResult(2); // 6
    // 所有的react元件都必須遵守的一條規則: 
    // 對待props就像對待純函數一樣,遵循可以通過輸入确定輸出
</script>
           

六、綁定事件

  1. 事件綁定的函數的this的指向會改變,需要使用bind來綁定函數的指向
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="app">

    </div>
</body>

</html>

<script type="text/babel">
    class Demo extends React.Component {
      constructor(props) {
          super(props);
          // 讓函數的this指向class的執行個體
          this.handleClick = this.handleClick.bind(this);
      }

      handleClick (){
        this.getList();
      }
      
      getList() {
          alert('擷取清單資料');
      }

      render() {
        return (
            <div>
                <button onClick={this.handleClick}>
                click
              </button>
            </div>
        );
      }
    }

ReactDOM.render(
    <Demo />,
    document.getElementById('app')
)
</script>
           
  1. 事件傳參的方式

    react可以在{} 裡面執行一個函數的調用

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
    class Demo extends React.Component {
        constructor(props) {
            super(props);
            this.toDetail = this.toDetail.bind(this);
        }

    toDetail(id) {
        console.log(event);
        alert(id);
    }

    render() {
        return (
            <div>
                <ul>
                    <li> <button onClick={() => {this.toDetail(1001)}}>電影1</button> </li>
                    <li> <button onClick={() => {this.toDetail(1002)}}>電影2</button> </li>
                    <li> <button onClick={() => {this.toDetail(1003)}}>電影3</button> </li>
                </ul>
            </div>
        )
    }
}

ReactDOM.render(
    <Demo />,
    document.getElementById('root')
)
</script>
           

七、清單渲染

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
  <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
  <div id="root">

  </div>
</body>

</html>

<script type="text/babel">
  class List extends React.Component {
   constructor(props) {
     super(props);
   }

   render() {
    let heroList = this.props.heroList;
    return (
      <ul>
        {heroList.map(hero =>{
            return (
                <li key={hero.id}>
                  {hero.heroName} -- {hero.role}
                </li>
              )
            }
        )}
      </ul>
    )
   }
}

const heroList = [
  {id: 1, heroName: '亞瑟', role: '戰士'},
  {id: 2, heroName: '牛魔王', role: '戰士'},
  {id: 3, heroName: '魯班七号', role: '射手'}
];

ReactDOM.render(
<List heroList={heroList} />,
  document.getElementById('root')
);   

</script>
           

八、條件渲染

  1. 通過 if 來控制渲染内容
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
   <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
   <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
   <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="app">

    </div>
</body>

</html>

<script type="text/babel">

class Welcome extends React.Component {
   constructor(props) {
       super(props);
   }

   render() {
       // 使用if else判斷變量isLogin的值來決定顯示什麼内容
       if (this.props.isLogin) {
           return (
               <h1>歡迎回來, <button style={{color: 'blue'}}>登出</button></h1>
           )
       } else {
           return (
               <h1>你還沒登入, <button  style={{color: 'red'}}>請登入</button></h1>
           )
       }
   }    

}

ReactDOM.render(
   <Welcome isLogin={false}/>,
   document.getElementById('app') 
)
</script>
           
  1. 通過三目運算符來判斷

    使用三目運算符判斷變量isLogin的值來決定顯示什麼内容

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>三目運算符</title>
  <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
  <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
  <div id="app">

  </div>
</body>

</html>

<script type="text/babel">

class Welcome extends React.Component {
   constructor(props) {
       super(props);
   }

   render() {
       /**
       * 通過變量isLogin來決定顯示什麼内容
       * 使用三目運算符(内容較短用三目運算符)
       * 再長一點用上面if else的方式
       * 更長的内容封裝成一個元件更合适
       */
      return (
        this.props.isLogin?
        <h1>歡迎回來, <button style={{color: 'blue'}}>登出</button></h1>:
         <h1>你還沒登入, <button  style={{color: 'red'}}>請登入</button></h1>
      )
   }    

}

ReactDOM.render(
   <Welcome isLogin={true}/>,
   document.getElementById('app') 
)


</script>
           
  1. 通過與運算符 && 進行控制

    相當于if沒有else的情況

<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title>三目運算符</title>
  <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
  <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
  <div id="app">

  </div>
</body>

</html>

<script type="text/babel">

class Welcome extends React.Component {
   constructor(props) {
       super(props);
   }

   render() {
       /**
       * 如果值為true就顯示,為false不顯示,相當于vue的v-show
       */
      return (
        this.props.show && 
          <p>
            React 起源于 Facebook 的内部項目,因為該公司對市場上所有 JavaScript MVC 架構,都不滿意,就決定自己寫一套,用來架設 Instagram
            的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。
          </p>
      )
   }    

}

ReactDOM.render(
   <Welcome show={true}/>,
   document.getElementById('app') 
)
</script>
           

九、this.state和this.setState

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title>三目運算符</title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
     <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
     <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="app">

    </div>
</body>

</html>

<script type="text/babel">

class Welcome extends React.Component {
   constructor(props) {
       super(props);
    // state的初始值
    this.state = {
         show: true
    }
    this.toggleMsg = this.toggleMsg.bind(this);
   }

toggleMsg(flag) {
  // 修改state裡show的值
    this.setState({
        show: flag
   })
}

   render() {
      return (
        <div>
        <button onClick={()=> {this.toggleMsg(true)}}>顯示</button>
        <button onClick={()=> {this.toggleMsg(false)}}>隐藏</button>
        <hr />
        {this.state.show && 
                <p>React 起源于 Facebook 的内部項目,因為該公司對市場上所有 JavaScript MVC       
                      架構,都不滿意,就決定自己寫一套,用來架設 Instagram
                      的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。
                  </p>
        }
        </div>
      )
   }    
}

ReactDOM.render(
   <Welcome />,
   document.getElementById('app') 
)
</script>
           

十、樣式和屬性

  1. class使用className代替
  2. style需要用{{}},外面的{}代表這是js代碼,裡面的{}則是個js對象
  3. 屬性是個變量加上{}即可
<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
     <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
     <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
     <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
    <style>
        .green {
            color: green;
        }
    </style>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
    let bg = '#999';
    let imgUrl = 'https://ss2.baidu.com/6ONYsjip0QIZ8tyhnq/it/u=1598000148,3084276147&fm=58&s=36F6EC36C8A47E92227DC7C502007026';

    ReactDOM.render(
        <div>
            <p style={{backgroundColor: bg,width: '200px'}}>hello react</p>
            <p className="green">我的react</p>
            <img src={imgUrl}/>
        </div>,

        document.getElementById('root')
    )
</script>
           

十一、生命周期

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
  <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
  <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
    /**
 * react的生命周期分成三種
 * 1. mount 挂載
 * 2. update 更新
 * 3. unmount 解除安裝
 */

 class Hello extends React.Component {

    componentWillMount() {
        console.log('即将挂載');
    }

    componentDidMount() {
        console.log('已挂載');
    }

    componentWillUpdate(nextProps, nextState) {
        console.log('将要更新');
    }

    componentDidUpdate(prevProps, prevState) {
        console.log('更新完畢');
    }

    // 預設每一次的修改都觸發頁面更新,此函數用于幹預是否要更新,用于性能優化,
    shouldComponentUpdate(nextProps, nextState) {

    }

    componentWillUnmount() {
        console.log('将要解除安裝');
    }

    render() {
        return <div>生命周期</div>
    }
 }

ReactDOM.render(
  <Hello name="world"/>,
  document.getElementById('root')
);
</script>
           

十二、表單

  1. 單個input标簽輸入,讓輸入的資料與react資料流同步
<!DOCTYPE html>
<html>

<head>
  <meta charset="UTF-8">
  <title></title>
  <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
  <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
  <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
  <div id="root">

  </div>
</body>

</html>

<script type="text/babel">

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''};

    this.handleChange = this.handleChange.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  handleChange(event) {
    this.setState({value: event.target.value});
  }

  handleSubmit(event) {
    alert('你輸入的使用者名是: ' + this.state.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <p>
          使用者名:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </p>
        <input type="submit" value="送出" />
      </form>
    );
  }
}

ReactDOM.render(
  <NameForm />,
  document.getElementById('root')
)
</script>
           
  1. 多個input表單輸入

    如果有多個input标簽輸入,我們是否需要為每一個input綁定一個事件呢,會不會太麻煩了,

    其實不用,我們可以像下面這樣來處理

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
class Reservation extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      username: 'huruqing',
      password: 123456,
            msg: ''
    };

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const target = event.target;
    const value = target.value;
    const name = target.name;

    this.setState({
      [name]: value
    });
  }

  render() {
    return (
            <div>
                 <form>
                        <label>
                            使用者名:
                            <input
                                name="username"
                                type="text"
                                value={this.state.username}
                                onChange={this.handleChange} />
                        </label>
                        <br />
                        <label>
                            密碼:
                            <input
                                name="password"
                                type="text"
                                value={this.state.password}
                                onChange={this.handleChange} />
                        </label>
                    </form>
                    <p>
                        你輸入的使用者名是: {this.state.username} <br/>
                        你輸入的密碼是:   {this.state.password}
                    </p>
            </div>
    );
  }
}

ReactDOM.render(
  <Reservation />,
  document.getElementById('root')
)
</script>
           

十三、擷取真實的DOM節點

通過ref可以擷取真實dom節點,需要確定節點已經挂載

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
    class MyComponent extends React.Component {
        constructor(props) {
            super(props);
            this.handleClick = this.handleClick.bind(this);
        }
        handleClick() {
            this.refs.myTextInput.focus();
        }
        render() {
            return (
                <div>
                    <input type="text" ref="myTextInput" />
                    <input type="button" value="擷取焦點" onClick={this.handleClick} />
                </div>
            )
        }
}

ReactDOM.render(
    <MyComponent />,
    document.getElementById('root')
);
</script>
           

十四、this.props.children

this.props 對象的屬性與元件的屬性一一對應,但是有一個例外,就是 this.props.children 屬性。它表示元件的所有子節點

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
    <script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
</head>

<body>
    <div id="root">

    </div>
</body>

</html>

<script type="text/babel">
class NotesList extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return (
      <ol>
      {
        React.Children.map(this.props.children, function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
    }
}

ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);
</script>
           

參考:

React 入門執行個體教程

http://www.ruanyifeng.com/blog/2015/03/react.html

React中文文檔

https://react.docschina.org/docs/hello-world.html

繼續閱讀