中文字幕一区二区人妻电影,亚洲av无码一区二区乱子伦as ,亚洲精品无码永久在线观看,亚洲成aⅴ人片久青草影院按摩,亚洲黑人巨大videos

絕對(duì)初學(xué)者學(xué)習(xí)React,第三部分

發(fā)布于:2021-02-01 16:10:20

0

81

0

javascript react 初學(xué)者 教程

這是我第一次在博客上發(fā)表的關(guān)于學(xué)習(xí)React的文章的延續(xù)。我一直在努力學(xué)習(xí)reactjs.org,上一次,我在構(gòu)建一個(gè)基本的tic-tac-toe游戲方面取得了進(jìn)展。在這篇博文中,我將完成它?。ㄏM绱耍。?/span>

所以當(dāng)我們上次結(jié)束時(shí),我剛剛對(duì)用戶選擇正方形的能力進(jìn)行了編碼。但他們只能把方塊變成“X”-es,沒有任何機(jī)制讓任何人獲勝。顯然,我們還有很多事情要做:

 

好吧,那么。。。什么?這篇課文有點(diǎn)混亂。我認(rèn)為這是在說,我們不希望董事會(huì)必須不斷地查詢每個(gè)方塊的狀態(tài),以確定是否有人贏得了比賽。這聽起來像正方形將發(fā)送他們的狀態(tài)時(shí),他們更新(這應(yīng)該只發(fā)生一次)和董事會(huì)將保持跟蹤它從那一點(diǎn)。但是,就像我說的,我不確定,因?yàn)檫@段文字不是很清楚。

所以,這一節(jié)的標(biāo)題是“提升狀態(tài)”,這是我看到的下一段文字:

 

我不得不讀幾遍來解析它,但聽起來好像是說,每當(dāng)你想讓兩個(gè)組件互相對(duì)話時(shí),它們必須通過父組件來實(shí)現(xiàn)。我不知道為什么。

……或者這篇文章(和上一篇文章)是說這樣做是一種推薦的做法?是不是因?yàn)槿魏我粋€(gè)孩子都可以將自己的狀態(tài)傳遞給父母,任何父母都可以設(shè)置孩子的狀態(tài),但孩子不能通過父母與其他孩子交談?這就是為什么鼓勵(lì)“提升狀態(tài)”成為父母的原因嗎?

這里的一些解釋會(huì)非常有用。

我將此constructor添加到Board中,以將電路板的狀態(tài)初始化為九個(gè)空方塊:

constructor(props) {     super(props);     this.state = {       squares: Array(9).fill(null)     };   }

不過,在示例代碼中,從squares: Array...開始的行的末尾有一個(gè)懸空的逗號(hào)。我去掉了這個(gè)懸垂的逗號(hào),我認(rèn)為這是一個(gè)打字錯(cuò)誤。

初始化this.state.squares的語法與初始化單個(gè)方塊中的this.state.value的語法相似:

this.state = {       value: null     };


this.state = {       squares: Array(9).fill(null)     };

…除此之外,我們沒有使用單個(gè)Square中的單個(gè)value,而是使用Array9值,每個(gè)值默認(rèn)設(shè)置為null。我想是吧。

 

我甚至不知道發(fā)生了什么,但我現(xiàn)在看到了,是的。這里:

renderSquare(i) {     return <Square value={i} />;   }

…當(dāng)我們渲染一個(gè)正方形時(shí),我們向它發(fā)送值i,該值由它在網(wǎng)格中的位置決定:

<div className="board-row">           {this.renderSquare(0)}           {this.renderSquare(1)}           {this.renderSquare(2)} </div>

所以i = 1, 2, 3, ...。但是Square類中的實(shí)際render()方法是:

render() {     return (       <button className="square"         onClick={() => this.setState({value: 'X'})}>         {this.state.value}       </button>         ); }

它完全忽略傳遞給它的i,它成為其state的未使用部分:

constructor(props) {     super(props);     this.state = {       value: null     }; }

…并使用this.setState({value: 'X'})}將值設(shè)置為X,而不管傳遞給它的值是多少。假設(shè)下一步,我們將修復(fù)此行為,并允許將狀態(tài)設(shè)置為XO,具體取決于傳遞給renderSquare()的值。

由于我們?cè)?/span>Board.state.squares中定義了電路板的狀態(tài)(我們將在將來更新),因此我們可以通過改變renderSquare()方法將一個(gè)正方形的狀態(tài)(從該數(shù)組)傳遞給正方形:

renderSquare(i) {     return <Square value={i} />;  }

變成

renderSquare(i) {     return <Square value={this.state.squares[i]} />;   }

好的,既然游戲的狀態(tài)被保存在Board中,任何特定的Square都不能直接更新游戲狀態(tài),因?yàn)閷?duì)象不能直接編輯其他對(duì)象的狀態(tài)。下一部分有點(diǎn)復(fù)雜。

首先,如果Square不再跟蹤游戲的狀態(tài),我們可以完全刪除constructor,因?yàn)樗龅囊磺卸际窃O(shè)置Square的狀態(tài):

class Square extends React.Component {     constructor(props) {       super(props);       this.state = {         value: null      }; }         render() {          return (             <button className="square"                    onClick={() => this.setState({value: 'X'})}>                    {this.state.value}             </button>    );      } }

變成

class Square extends React.Component {     render() {         return (             <button className="square"                   onClick={() => this.setState({value: 'X'})}>                   {this.state.value}             </button>              ) ;      } }

然后,我們將把一個(gè)函數(shù)從Board傳遞到Square,它告訴Square如何處理點(diǎn)擊,所以

renderSquare(i) {     return <Square value={this.state.squares[i]} />;  }

變成

renderSquare(i) {      return (         <Square               value   = {this.state.squares[i]}               onClick = {() => this.handleClick(i)}          />        ); }

為便于閱讀,行縮進(jìn),return之后必須有一個(gè)()圍繞其內(nèi)容。否則,JavaScript自動(dòng)插入分號(hào)可能會(huì)破壞代碼。(誰認(rèn)為這是個(gè)好主意?)

當(dāng)然,這意味著Square也應(yīng)該更新。我們應(yīng)該在button的定義中使用this.props.onClick()而不是this.setState({value: 'X'})}

class Square extends React.Component {       render() {           return (              <button className="square"                    onClick={() => this.setState({value: 'X'})}>                    {this.state.value}              </button>             );       } }

變成

class Square extends React.Component {       render() {            return (                <button className="square"                        onClick={() => this.props.onClick()>                       {this.state.value}                </button>              );        } }

哦,當(dāng)然,this.state.value應(yīng)該更改為this.props.value,因?yàn)?/span>Square的狀態(tài)將從Board發(fā)送到Squareprops

class Square extends React.Component {       render() {            return (                <button className="square"                       onClick={() => this.props.onClick()>                       {this.state.value}                </button>               );       } }

變成

class Square extends React.Component {      render() {           return (                <button className="square"                        onClick={() => this.props.onClick()>                        {this.props.value}                </button>               );       } }

我仍然不明白這一切是如何結(jié)合在一起的,但我猜這個(gè)解釋正在進(jìn)行中。

 

哦,是的,看,在那兒。我再次在終端中運(yùn)行npm start,等待代碼運(yùn)行的時(shí)間非常長(zhǎng)。(還有其他人有這個(gè)問題嗎?)當(dāng)它出現(xiàn)時(shí),我會(huì)在瀏覽器中看到一個(gè)錯(cuò)誤頁面:

 

我做了什么?

哦,看起來我忘了在我的代碼中將{this.state.value}更新為{this.props.value},盡管我是在這里寫的。讓我們改變一下,再試一次:

 

太好了,成功了!它應(yīng)該以這種特定的方式崩潰,因?yàn)槲覀冞€沒有在this.props中定義onClick()函數(shù)。

所以在我有this.props.onClick()的地方,我應(yīng)該換成this.props.handleClick()。為了清楚起見,讓我在這里復(fù)制整個(gè)index.js文件:

import React from 'react'; import ReactDOM from 'react-dom'; import './index.css'; class Square extends React.Component {   render() {     return (       <button className="square"         onClick={() => this.props.handleClick()}>         {this.props.value}       </button>     );   } } class Board extends React.Component {   constructor(props) {     super(props);     this.state = {       squares: Array(9).fill(null)     };   }   renderSquare(i) {     return (       <Square         value={this.state.squares[i]}         onClick={() => this.handleClick(i)}       />;     );   }   render() {     const status = 'Next player: X';     return (       <div>         <div className="status">{status}</div>         <div className="board-row">           {this.renderSquare(0)}           {this.renderSquare(1)}           {this.renderSquare(2)}         </div>         <div className="board-row">           {this.renderSquare(3)}           {this.renderSquare(4)}           {this.renderSquare(5)}         </div>         <div className="board-row">           {this.renderSquare(6)}           {this.renderSquare(7)}           {this.renderSquare(8)}         </div>       </div>     );   } } class Game extends React.Component {   render() {     return (       <div className="game">         <div className="game-board">           <Board />         </div>         <div className="game-info">           <div>{/* status */}</div>           <ol>{/* TODO */}</ol>         </div>       </div>     );   } } // ======================================== ReactDOM.render(   <Game />,   document.getElementById('root') );

我還漏掉了代碼中的其他一些東西。在這里做筆記,并在終端中編輯代碼,同時(shí)閱讀教程可能會(huì)有點(diǎn)混亂。我認(rèn)為以上所有內(nèi)容都和教程中的一樣,所以讓我們繼續(xù)。

為了消除第二個(gè)錯(cuò)誤(“_this.props.onClick不是函數(shù)”)并記住我們將onClick重命名為handleClick,我們現(xiàn)在必須在Board中定義handleClick方法:我不確定我真的從這個(gè)教程中學(xué)到了什么。不僅僅是復(fù)制和粘貼預(yù)先編寫的代碼。不過,我會(huì)堅(jiān)持到底。

Board中,我們現(xiàn)在定義handleClick()方法:

handleClick(i) {      const squares = this.state.squares.slice();      squares[i] = 'X';      this.setState({squares: squares});  }

在我讀之前,讓我看看我是否能猜出這是在做什么。首先,它是一個(gè)接受單個(gè)參數(shù)的函數(shù),這個(gè)參數(shù)是板上正方形的索引(無論是0-8還是1-9,我都不知道JavaScript是基于0還是基于1)。然后,它在方法中創(chuàng)建一個(gè)ant局部變量,并將其初始化為自己的state.squares。如果squares已經(jīng)是一個(gè)數(shù)組,我不知道為什么slice()需要出現(xiàn)在那里。另外,當(dāng)我們?cè)谙乱恍兄懈钠湟粋€(gè)元素的值時(shí),為什么將squares聲明為const?最后,我們用setState設(shè)置狀態(tài)。在JavaScript中,變量似乎是通過值傳遞的,因此我們必須顯式地將squares.state的值復(fù)制到一個(gè)局部變量中,然后編輯該變量,然后將編輯后的變量傳遞回以更改狀態(tài)。有多少是對(duì)的?

 

……好吧,我想我以后會(huì)知道的。

這是字面上的下一段,開始解釋這一點(diǎn)。如果你下次再談的話,為什么還要說“我們稍后再解釋”?這就是為什么他們建議這樣做:

 

對(duì)我來說很自然的方法是直接編輯Square的狀態(tài),但是教程推薦的方法是創(chuàng)建一個(gè)新對(duì)象,而不是改變現(xiàn)有對(duì)象。本教程建議盡可能保持對(duì)象不變,以便于檢測(cè)更改,并且應(yīng)用程序可以輕松恢復(fù)到以前的狀態(tài),以及其他好處。

 

天啊??梢?。也許是我,因?yàn)槲覜]有很強(qiáng)的JavaScript/反應(yīng)式前端編程背景,但本教程似乎從一個(gè)概念跳到了另一個(gè)概念,基本上沒有分段。似乎沒有一個(gè)明確的目標(biāo)或?qū)W習(xí)途徑。我覺得我只是在學(xué)習(xí)一個(gè)隨機(jī)的概念,然后復(fù)制一些代碼,然后繼續(xù)做下一件事。到目前為止還不怎么喜歡。

 

好吧,這看起來很簡(jiǎn)單。由于正方形本身不包含任何狀態(tài),因此它將通過在Board中調(diào)用此函數(shù)來呈現(xiàn)。

好吧,但為什么。沒有解釋,我們繼續(xù)下一件事。

在更改Board中的renderSquare()函數(shù)之前,我們將添加在電路板上繪制O以及Xes的功能。我們?cè)?/span>Board“sconstructor中設(shè)置初始狀態(tài):

class Board extends React.Component {      constructor(props) {           super(props);           this.state = {               squares: Array(9).fill(null)           };      } }

變成

class Board extends React.Component {     constructor(props) {         super(props);         this.state = {             squares: Array(9).fill(null),             xIsNext: true         };     } }

同樣,在xIsNext: true的末尾有一個(gè)懸空的逗號(hào),我已經(jīng)去掉了。這是故意的嗎?

所以xIsNext是一個(gè)布爾值,我們每次渲染正方形時(shí)都會(huì)翻轉(zhuǎn)它。當(dāng)我們重寫renderSquare()時(shí)(我想),我們將把xIsNext從false翻轉(zhuǎn)到true,反之亦然,在我們決定繪制XO之前,檢查xIsNext的狀態(tài)。我們改變

handleClick(i) {     const squares = this.state.squares.slice();     squares[i] = 'X';     this.setState({squares: squares}); }


handleClick(i) {     const squares = this.state.squares.slice();     squares[i] = this.state.xIsNext ? 'X' : 'O';     this.setState({       squares: squares,       xIsNext: !this.state.xIsNext     }); }

 

哦,打字錯(cuò)誤。我來修一下。

 

快到了!正如你在上面看到的,游戲仍然沒有宣布勝出。我想這是下一步要做的事情,但在我們做之前,教程希望我們呈現(xiàn)一個(gè)消息,說輪到誰了。我們添加一行:

const status = 'Next player: ' + (this.state.xIsNext ? 'X' : 'O');

…在Boardrender()函數(shù)的頂部(現(xiàn)在,它總是說X是下一個(gè)玩家):

 

我也注意到,當(dāng)我編輯index.js文件時(shí),React會(huì)自動(dòng)重新呈現(xiàn)localhost:3000處的頁面。那太好了!

好的,最后一件事最后一件事:我們?nèi)绾涡紕倮撸?/span>

我現(xiàn)在真的沒有精力了,所以我很高興這一節(jié)快結(jié)束了。

  

我更喜歡一個(gè)教程,從最小的可理解的代碼開始,從那里開始工作,而不是從一個(gè)骨架開始,一遍遍地說“好的,現(xiàn)在復(fù)制并粘貼這個(gè)內(nèi)容到那里”。

在無意中復(fù)制了更多的代碼之后。。。

  

本教程還有一節(jié),但我嚴(yán)重缺乏完成它的動(dòng)力。我想我想嘗試一個(gè)不同的教程或書,從基礎(chǔ)開始,并建立在他們的基礎(chǔ)上。

我要退出這個(gè)教程75%的方式通過。我覺得很沮喪,而且我覺得我實(shí)際上沒有學(xué)到多少反應(yīng)。也許是在反應(yīng)js.org我應(yīng)該考慮為本教程做一些焦點(diǎn)小組測(cè)試,因?yàn)槲掖_信我不是唯一一個(gè)有這種反應(yīng)的人。