1. 程式人生 > >要掌握的react的一些操作

要掌握的react的一些操作

  這裡只是對自己的學習進行一次總結,也是為了讓自己以後如果長時間不使用快速記憶起來的筆記,如果想要學習,還是去官網看文件比較好一些。、

  注意 下面的程式碼的 script標籤的type型別都為 “text/babel”

目錄

一、無狀態元件

二、函式式宣告

三、this以及事件物件

四、操作dom元素

五、父子元件傳值

六、在瀏覽器中支援import export

一、 無狀態的元件

  只是普通的變數是沒有狀態的, 只有元件才有狀態或無狀態

  react是單向資料流

  狀態其實就是讓資料驅動檢視的響應式資料

 1 let a = '這裡是div元素111
'; 2 3 setTimeout(() => { 4 console.log('函式執行了'); 5 a = '改變之後的值' 6 },2000); 7 8 const element = ( 9 <div>{a}</div> 10 ); 11 12 ReactDOM.render( 13 element, 14 document.getElementById('app') 15 )

如果你學習過vue的話,那種雙向資料繫結用的 Object.defineProperty() 叫資料劫持,然後用了訂閱釋出(觀察者)那種模式,資料改變之後,會驅動著檢視去改變

react必須要通過 setState() 這個元件的例項化物件去呼叫去改變自身的state才會去驅動檢視是改變的,所以上面的那種就算資料改變了,但是檢視是沒有進行改變的。

看下面的es6的這種寫法

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4     this.state = { // 只有在state裡面的內容才是有無狀態的
 5       a: '這裡是div元素'
 6     };
 7 
 8     setTimeout(() => {
 9       this
.setState({ // 這裡必要要用 setState這個方法來改變值才會驅動檢視去改變 如果 this.state.a = 'sdfsd' 這樣是不會驅動檢視去改變的 10 a: '改變之後的值' 11 }) 12 }, 1000) 13 } 14 render() { 15 return ( 16 <div> 17 {this.state.a} 18 </div> 19 ); 20 } 21 } 22 23 ReactDOM.render( 24 <Element/>, 25 document.getElementById('app') 26 )

 

二、 函式式宣告

  其實之前一直都是使用的變數去指代html元素,沒有使用過 class 那種,現在先使用ES5的寫法去寫一寫什麼是函式式宣告。

  先看一下之前的寫法吧

 1 const Head = (
 2   <h2>Head頭部</h2>
 3 );
 4 const Foot = (
 5   <h2>底部</h2>
 6 );
 7 const element = (
 8   <div>
 9     {
10       Head
11     }
12     <h2>Element內容</h2>
13     {
14       Foot
15     }
16   </div>
17 );
18 
19 ReactDOM.render(
20   element,
21   document.getElementById('app')
22 )

函式式宣告是什麼樣子的呢

 1 const Head = function () {
 2   return (
 3     <h2>Head頭部</h2>
 4   )
 5 };
 6 const Foot = function () {
 7   return (
 8     <h2>底部</h2>
 9   )
10 };
11 const Element = function() {
12   return (
13     <div>
14       <Head/>
15       <h2>Element內容</h2>
16       <Foot/>
17     </div>
18   );
19 };
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

可以很清晰的看到他們兩個的區別,一個是使用變數來代表的,另外的一個是使用的元件形式代表的,開發中的寫法都是使用ES6的class繼承宣告來寫元件的

看一下函式宣告的傳值

 1 const Head = function (props) {
 2   return (
 3     <h2>{props.title}</h2>
 4   )
 5 };
 6 const Foot = function (props) {
 7   return (
 8     <h2>{props.con}</h2>
 9   )
10 };
11 const Element = function() {
12   return (
13     <div>
14       <Head
15         title={'頭部資訊啊'}
16       />
17       <h2>Element內容</h2>
18       <Foot
19         con={'底部的內容啊'}
20       />
21     </div>
22   );
23 };
24 
25 ReactDOM.render(
26   <Element></Element>,
27   document.getElementById('app')
28 )

這個樣子和vue其實是挺像的,在標籤上面寫自定義的屬性,子元件就可以接收到,等先這樣看看,後面會使用class寫的,class寫起來感覺還容易理解一些。

注意: 函式式宣告元件

  1. 元件的首字母必須是大寫

  2. 不要使用H5新標籤

下面看一個狀態改變驅動檢視的例子

 1 const Head = function (props) {
 2   return (
 3     <h2>{props.title}</h2>
 4   )
 5 };
 6 const Foot = function (props) {
 7   return (
 8     <h2>{props.con}</h2>
 9   )
10 };
11 
12 class Element extends React.Component{
13   constructor() {
14     super();
15     this.state = {
16       title: '頭部資訊',
17       con: '底部資訊'
18     };
19 
20     setTimeout(() => {
21       this.setState({
22         title: '頭部資訊改變'
23       })
24     },2000)
25   }
26   render() {
27     return (
28       <div>
29         <Head
30           title={this.state.title}
31         />
32         <h2>Element內容</h2>
33         <Foot
34           con={this.state.con}
35         />
36       </div>
37     );
38   }
39 }
40 
41 ReactDOM.render(
42   <Element></Element>,
43   document.getElementById('app')
44 )

這樣就可以和上面那種結合起來了,以後所有的元件都用class來寫了,就不用function那種形式了。

 

三、 this以及事件物件

  react元件中的this和事件物件的不同寫法有的寫法是需要繫結this的

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4   }
 5 
 6   btn() {
 7     console.log(this);  // 可以看到這裡列印的是 undefined
 8   }
 9 
10   render() {
11     return (
12       <div>
13        <h1>title</h1>
14         <button onClick={this.btn}>按鈕</button>
15       </div>
16     );
17   }
18 }
19 
20 ReactDOM.render(
21   <Element></Element>,
22   document.getElementById('app')
23 )

看到上面列印的this是undefined,下面有幾種寫法可以更正this指向例項化物件的

第一種 更正this和事件物件

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4     this.btn = this.btn.bind(this);  // 在這裡更正,官方推薦的也是這種寫法
 5   }
 6 
 7   btn(e) {
 8     console.log(this);
 9     console.log(e.target)
10   }
11 
12   render() {
13     return (
14       <div>
15        <h1>title</h1>
16         <button onClick={this.btn}>按鈕</button>
17       </div>
18     );
19   }
20 }
21 
22 ReactDOM.render(
23   <Element></Element>,
24   document.getElementById('app')
25 )

需要注意的是上面的那種寫法如果傳遞引數的話,那麼事件物件就是最後一個沒有物件引數的和js中的bind一樣

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4     this.btn = this.btn.bind(this);  // 在這裡更正,官方推薦的也是這種寫法
 5   }
 6 
 7   btn() {
 8     console.log(this);
 9     console.log(arguments)  // 因為下面的函式傳遞了引數,這裡第二個引數才是事件物件
10   }
11 
12   render() {
13     return (
14       <div>
15        <h1>title</h1>
16         <button onClick={this.btn(1)}>按鈕</button>
17       </div>
18     );
19   }
20 }
21 
22 ReactDOM.render(
23   <Element></Element>,
24   document.getElementById('app')
25 )

第二種 在行內bind

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4   }
 5 
 6   btn() {
 7     console.log(this);
 8     console.log(arguments)
 9   }
10 
11   render() {
12     return (
13       <div>
14        <h1>title</h1>
15         <button onClick={this.btn.bind(this, 1)}>按鈕</button>  // 直接寫到行內,在這裡改變this的指向,同樣的問題,那個引數的事件物件是最後一個
16       </div>
17     );
18   }
19 }
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

第三種 在一個函式裡面執行它

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4   }
 5 
 6   btn(e) {
 7     console.log(this);
 8     console.log(arguments)
 9   }
10 
11   render() {
12     return (
13       <div>
14        <h1>title</h1>
15         <button onClick={(e) => {
16           this.btn(e,11);
17         }}>按鈕</button>
18       </div>
19     );
20   }
21 }
22 
23 ReactDOM.render(
24   <Element></Element>,
25   document.getElementById('app')
26 )

第四種 改變函式的寫法

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4   }
 5 
 6   btn = (e) => {
 7     console.log(this);
 8     console.log(e.target)
 9   }
10 
11   render() {
12     return (
13       <div>
14        <h1>title</h1>
15         <button onClick={this.btn}>按鈕</button>
16       </div>
17     );
18   }
19 }
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

當然了這種方式如果要傳遞引數的話還是需要bind的。

 

四、 操作dom元素

  如果想要在react中操作dom元素的話,有幾種方法

第一種 直接使用js的方法

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4 
 5   }
 6 
 7   btn = () => {
 8     const ele = document.querySelector('.h1');
 9     console.log(ele);
10 
11   };
12 
13   render() {
14     return (
15       <div>
16        <h1 className='h1'>title</h1>
17         <button onClick={this.btn}>按鈕</button>
18       </div>
19     );
20   }
21 }
22 
23 ReactDOM.render(
24   <Element></Element>,
25   document.getElementById('app')
26 )

第二種 通過事件物件

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4 
 5   }
 6 
 7   btn = (e) => {
 8     console.log(e.target);
 9   };
10 
11   render() {
12     return (
13       <div>
14        <h1 className='h1'>title</h1>
15         <button onClick={this.btn}>按鈕</button>
16       </div>
17     );
18   }
19 }
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

第三種 ref

  和vue一樣

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4 
 5   }
 6 
 7   btn = (e) => {
 8     console.log(this.refs.abc)  // 在這裡獲取它
 9   };
10 
11   render() {
12     return (
13       <div>
14        <h1 ref="abc">title</h1>  // 這裡定義一個字串的名字
15         <button onClick={this.btn}>按鈕</button>
16       </div>
17     );
18   }
19 }
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

不過最新版本的不建議上面的那種寫法了,也是ref建議下面的寫法

以後我們就可以用下面這種最常用的方式

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4 
 5   }
 6 
 7   btn = (e) => {
 8     console.log(this.abc)
 9   };
10 
11   render() {
12     return (
13       <div>
14        <h1 ref={abc => {this.abc = abc}}>title</h1>
15         <button onClick={this.btn}>按鈕</button>
16       </div>
17     );
18   }
19 }
20 
21 ReactDOM.render(
22   <Element></Element>,
23   document.getElementById('app')
24 )

第四種 ReactDOM.findDOMNode

 1 class Element extends React.Component{
 2   constructor() {
 3     super();
 4 
 5   }
 6 
 7   btn = (e) => {
 8     console.log(this.abc)
 9 
10     console.log(ReactDOM.findDOMNode(this.abc));
11   };
12 
13   render() {
14     return (
15       <div>
16        <h1 ref={abc => {this.abc = abc}}>title</h1>
17         <button onClick={this.btn}>按鈕</button>
18       </div>
19     );
20   }
21 }
22 
23 ReactDOM.render(
24   <Element></Element>,
25   document.getElementById('app')
26 )

ref如果標記的是元件,那麼ref他就是元件,但是findDOMNode這種方式是獲取DOM元素的,就算裡面的引數是元件,也是獲得DOM元素

 

五、 父子元件傳值

  核心思想 

  父元件給子元件傳值 直接在元件上面新增屬性就可以了 子元件通過props訪問,得到 其實是建構函式例項化的時候傳過去了

  子元件給父元件傳值 其實是父元件給子元件傳一個函式,子元件呼叫的時候把 要傳遞的資料 放到 父元件傳遞過來的函式 的引數裡面,然後父元件再去做他自己的操作

Item子元件


1
class Item extends React.Component { 2 constructor (props) { 3 super(props); 4 this.state = { 5 sub: this.props.data 6 } 7 } 8 9 componentWillReceiveProps(nextProps) { 10 console.log('執行了嗎'); 11 console.log(nextProps); 12 } 13 14 render() { 15 console.log('子元件列印this'); 16 console.log(this); 17 console.log(this.props); 18 19 return ( 20 <div> 21 <p>Item元件</p> 22 <h1>{this.state.sub.res}</h1> 23 <input type="button" defaultValue="這裡" onClick={this.props.supFn.bind(this,'子元件引數')} /> 24 <input type="button" 25 defaultValue="22" 26 onClick={() => { 27 this.props.supFn('引數2') 28 }} 29 30 /> 31 </div> 32 ); 33 } 34 }

父元件

 1 class Main extends React.Component {
 2   constructor() {
 3     super();
 4     this.superFn = this.superFn.bind(this);
 5 
 6   }
 7   state = {
 8     data: {
 9       res: '裡面的資料'
10     }
11   };
12 
13   superFn(a) {
14     console.log('父元件的函式');
15     console.log(`${a}`);
16     let data = {
17         res: '修改過後'
18     };
19     console.log(data);
20 
21     this.setState({
22       data: data
23     })
24   }
25   render() {
26     return (
27       <div>
28         <p>主頁面</p>
29           <p>{this.state.data.res}</p>
30         <Item supFn={this.superFn} data={this.state.data} aaa="傳值啊"></Item>
31       </div>
32     );
33   }
34 }
35 
36 ReactDOM.render(
37   <Main />,
38   document.getElementById('app')
39 )

六、在瀏覽器中支援import export

  要在伺服器環境下開啟檔案

  在谷歌瀏覽器輸入框中輸入

然後就可以使用模組匯出匯出功能了

1 // 2.js
2 const a = 1;
3 const b = 2;
4 
5 export default {a, b};

 

1 <script type="module">
2     // 要伺服器環境下開啟  http服務
3     // chrome//flags 開啟那個許可權
4     import a from './2.js';
5     console.log(a)
6 </script>

如果你看了我的文章有了一些收穫我會非常高興的,由於能力有限,文章有的部分解釋的不到位,希望在以後的日子裡能慢慢提高自己能力,如果不足之處,還望指正。