react構建
by Scott Domes
由斯科特·多姆斯(Scott Domes)
您應該了解的有關React的一切:開始構建所需的基礎知識 (Everything You Should Know About React: The Basics You Need to Start Building)
Are you curious about React and haven’t had the chance to learn it? Or maybe you’ve tried tutorials in the past, but struggled to master the core concepts? Or maybe you’ve learned the basics, but want to consolidate your knowledge? Either way, this article is for you.
您是否對React感到好奇,還沒有機會學習它? 或者,也許您過去曾經嘗試過教程,但卻難以掌握核心概念? 或者,也許您已經學習了基礎知識,但想鞏固您的知識? 無論哪種方式,本文都適合您。
We’re going to build a simple React music player, layering on new React concepts as we go.
我們將構建一個簡單的React音樂播放器,并在開發過程中以新的React概念為基礎。
Here’s what we’ll cover:
這是我們要介紹的內容:
- What is a React component? 什么是React組件?
- ReactDOM rendering ReactDOM渲染
- Class vs functional components 類與功能組件
- JSX JSX
- State 州
- Event handling 事件處理
- Asynchronous setState 異步setState
- Props 道具
- Refs 參考
That’s just about everything you need to build and maintain a React application. But we’re going to introduce it piece-by-piece.
這就是構建和維護React應用程序所需的一切。 但是,我們將逐個介紹它。
建立 (Setup)
Here’s the situation: a small start-up has reached out to you for your help. They’ve created a page for users to upload music and have it visualized in glowing colour. But they need you to do the hard part—AKA to make it work.
情況就是這樣:一家小型創業公司已經向您尋求幫助。 他們創建了一個頁面供用戶上傳音樂,并以發光的顏色對其進行可視化。 但是他們需要您盡力而為-使其工作。
To get going, make a new project directory and add the following three files.
首先,創建一個新的項目目錄并添加以下三個文件 。
Make sure you’re using an up-to-date version of Chrome with this tutorial, otherwise the animations in the code above won’t work.
請確保您在本教程中使用的是最新版的Chrome ,否則上面代碼中的動畫將不起作用。
Thanks to Steven Fabre for the play button CSS and Justin Windle for visualization code (you can view the original here).
感謝Steven Fabre提供CSS播放按鈕,以及Justin Windle的可視化代碼( 您可以在此處查看原始內容 )。
Open up index.html
in both a code editor and your browser, and let’s get started!
在代碼編輯器和瀏覽器中打開index.html
,讓我們開始吧!
什么是React? (What is React?)
React is a way to build user interfaces. It is only concerned with what you see on the front-end. React makes user interfaces very easy to build by cutting each page into pieces. We call these pieces components.
React是一種構建用戶界面的方法。 它只與您在前端看到的內容有關。 通過將每個頁面分成幾部分,React使用戶界面的構建非常容易。 我們稱這些部件為組件。
Here is an example of cutting a page into components:
這是將頁面切成組件的示例:
Each section highlighted above is considered a component. But what does this mean for a developer?
上面突出顯示的每個部分都被視為一個組件。 但這對開發人員意味著什么?
什么是React組件? (What is a React Component?)
A React component is a bit of code that represents a piece of the page. Each component is a JavaScript function that returns a piece of code that represents a piece of a web page.
React組件是代表一部分頁面的一些代碼。 每個組件都是一個JavaScript函數,該函數返回代表網頁的一段代碼。
To build a page, we call these functions in a certain order, put together the result, and show it to the user.
為了構建頁面,我們以一定的順序調用這些函數,將結果放在一起,并顯示給用戶。
Let’s write a component inside the <scri
pt> tag in inde
x.html with th
e type of “text/
babel”:
讓我們寫內部的部件的<scri
PT>噸ag in inde
x.html機智h th
èTY pe of “text/
巴別”:
<script type="text/babel"> function OurFirstComponent() { return ( // Code that represents the UI element goes here ); }</script>
When we call the OurFirstcomponent()
function, we will get back a piece of the page.
當我們調用OurFirstcomponent()
函數時,我們將返回頁面的一部分。
You can also write functions like this:
您還可以編寫如下函數:
const OurFirstComponent = () => { return ( // Stuff to make this component goes here );}
React uses a language called JSX that looks like HTML but works inside JavaScript, which HTML usually doesn’t do.
React使用一種叫做JSX的語言,它看起來像HTML,但是可以在JavaScript內運行,而HTML通常是不支持的。
You can add plain HTML to this section to make it appear on the UI:
您可以將純HTML添加到此部分,以使其出現在UI中:
<script type="text/babel"> function OurFirstComponent() { return ( <h1>Hello, I am a React Component!</h1> ); }</script>
When we call the OurFirstComponent()
function, we get back a bit of JSX. We can use something called ReactDOM to put it on the page.
當我們調用OurFirstComponent()
函數時,我們會得到一些JSX。 我們可以使用稱為ReactDOM的東西將其放在頁面上。
<script type="text/babel"> function OurFirstComponent() { return ( <h1>Hello, I am a React Component!</h1> ); }
const placeWeWantToPutComponent = document.getElementById('hook'); ReactDOM.render(OurFirstComponent(), placeWeWantToPutComponent);</script>
Now our <
h1> tag will be put inside the element with the ID of
hook. It should look like this when you refresh your browser:
現在,我們的<
h1>標記將被放置在具有鉤子ID of
的元素內。 刷新瀏覽器時,它應如下所示:
We can also write our component in JSX like so:
我們也可以像這樣在JSX中編寫組件:
ReactDOM.render(<OurFirstComponent />, placeWeWantToPutComponent);
This is standard — invoke your components like you are writing HTML.
這是標準的-就像編寫HTML一樣調用組件。
將組件放在一起 (Putting Components Together)
We can put React components inside other components.
我們可以將React組件放入其他組件中。
<script type="text/babel"> function OurFirstComponent() { return ( <h1>I am the child!</h1> ); }
function Container() { return ( <div> <h1>I am the parent!</h1> <OurFirstComponent /> </div> ); }
const placeWeWantToPutComponent = document.getElementById('hook'); ReactDOM.render(<Container />, placeWeWantToPutComponent);</script>
This is how we build our page out of pieces of React — by nesting components inside of each other.
這就是我們通過將組件嵌套在彼此之間,從而利用React片段構建頁面的方式。
類組件 (Class Components)
So far, we’ve been writing components as functions. These are called functional components.
到目前為止,我們一直在將組件編寫為函數。 這些稱為功能組件。
But you can write components another way, as JavaScript classes. These are called class components.
但是您可以使用另一種方式編寫組件,例如JavaScript類。 這些稱為類組件。
class Container extends React.Component { render() { return ( <div> <h1>I am the parent!</h1> <OurFirstComponent /> </div> ); }}
const placeWeWantToPutComponent = document.getElementById('hook');ReactDOM.render(<Container />, placeWeWantToPutComponent);
Class components must have a function called render()
. The render function returns the JSX of the component. They can be used the same way as functional components, like this:<AClassComponent
/>.
類組件必須具有一個稱為render()
的函數。 render函數返回組件的JSX。 它們可以與功能組件相同的方式使用,如下所示: <AClassComponent
/>。
You should use functional components over class components because they’re easier to read, unless you need component state (more on that soon).
您應該在類組件上使用功能組件,因為它們更易于閱讀,除非您需要組件狀態 (稍后會介紹更多)。
JSX中JavaScript (JavaScript in JSX)
You can put JavaScript variables inside of your JSX like this:
您可以像這樣將JavaScript變量放入JSX:
class Container extends React.Component { render() { const greeting = 'I am a string!'; return ( <div> <h1>{ greeting }</h1> <OurFirstComponent /> </div> ); }}
Now the ‘I am a string!’ will be inside the h1
.
現在,“我是弦樂!” 將在h1
。
You can also do more difficult stuff, like call a function:
您還可以執行更困難的工作,例如調用函數:
class Container extends React.Component { render() { const addNumbers = (num1, num2) => { return num1 + num2; }; return ( <div> <h1>The sum is: { addNumbers(1, 2) }</h1> <OurFirstComponent /> </div> ); }}
JSX陷阱 (JSX Gotchas)
Rename OurFirstComponent()
to PlayButton
. We want it to return the following:
將OurFirstComponent()
重命名為PlayButton
。 我們希望它返回以下內容:
<a href="#" title="Play video" class="play" />
But there’s a problem: class
is a keyword in JavaScript, so we can’t use it. So how do we give our <
;a> a class o
f play?
但是有一個問題: class
是JavaScript中的關鍵字,因此我們不能使用它。 那么,如何才能讓我們的<
;一>一CLA ss o
?F玩嗎?
Use a property called className
instead:
使用名為className
的屬性代替:
<script type="text/babel"> function PlayButton() { return <a href="#" title="Play video" className="play" />; }
class Container extends React.Component { render() { return ( <div> <PlayButton /> </div> ); } }
const placeWeWantToPutComponent = document.getElementById('hook'); ReactDOM.render(<Container />, placeWeWantToPutComponent);</script>
該組件在做什么? (What Is This Component Doing?)
Class components can store information about their current situation. This information is called state
, which is stored in a JavaScript object.
類組件可以存儲有關其當前情況的信息。 此信息稱為state
,它存儲在JavaScript對象中。
In the code below, we have an object representing our components state. It has a key
of isMusicPlaying
which has a value
of false
. This object is assigned to this.state
in the constructor
method, which is called when the class is first used.
在下面的代碼中,我們有一個表示組件狀態的對象。 它具有isMusicPlaying
key
,其value
false
。 該對象在constructor
方法中分配給this.state
,該方法在首次使用該類時被調用。
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; } render() { return ( <div> <PlayButton /> </div> ); }}
A constructor
method of a React component always needs to call super(props)
before anything else.
React組件的constructor
方法始終需要先調用super(props)
。
Okay, so what do we do with state
? Why does it exist?
好的,我們該如何處理state
? 為什么存在?
根據狀態更改React組件 (Changing Our React Component Based On State)
State is way to update our UI based on events.
狀態是基于事件更新我們的UI的方法。
In this tutorial, we will use state to change the play button from paused to playing based on the user clicking the play button.
在本教程中,我們將使用狀態來改變播放按鈕從暫停 打根據用戶點擊播放按鈕。
When the user clicks on the button, the state will update, which will then update the UI.
當用戶單擊按鈕時,狀態將更新,然后狀態將更新UI。
Here’s how we get started. We can look at the component state with this.state
. In the following code, we look at the state and use it to decide what text to present to the user.
這是我們的入門方法。 我們可以使用this.state
查看組件狀態。 在下面的代碼中,我們查看狀態并使用它來決定向用戶呈現什么文本。
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; }
render() { const status = this.state.isMusicPlaying ? 'Playing' : 'Not playing'; return ( <div> <h1>{ status }</h1> <PlayButton /> </div> ); }}
In the render function, this
is always referring to the component it is within.
在render函數中, this
始終是指其所在的組件。
But that’s not very useful unless we have a way to change this.state.isMusicPlaying
.
但這不是很有用,除非我們有辦法更改this.state.isMusicPlaying
。
當東西發生在我們的組件上 (When Stuff Happens to Our Component)
The user can interact with our components by clicking on the play button. We want to react (ha… ha…) to those events.
用戶可以通過單擊播放按鈕與我們的組件進行交互。 我們想對這些事件做出React(哈……哈……)。
We do that through functions that take care of events. We call these event handlers.
我們通過負責事件的功能來做到這一點。 我們稱這些事件處理程序 。
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; }
handleClick(event) { // Do something about the click };
render() { let status = this.state.isMusicPlaying ? 'Playing :)' : 'Not playing :('; return ( <div> <h1 onClick={this.handleClick.bind(this)}>{ status }</h1> <PlayButton /> </div> ); }}
When the user clicks on the h1
, our component will make the handleClick
function run. The function gets the event object as the argument, which means it can use it if it wanted to.
當用戶單擊h1
,我們的組件將使handleClick
函數運行。 該函數將事件對象作為參數,這意味著它可以在需要時使用它。
We use the .bind
method on handleClick
to make sure this
refers to the whole component, rather than just the h1
.
我們在handleClick
上使用.bind
方法,以確保this
引用的是整個組件,而不僅僅是h1
。
該組件應該做什么 (What This Component Should Be Doing)
When we change the state of our component, it will call the render function again.
當我們更改組件的狀態時,它將再次調用render函數。
We can change state with this.setState()
, if we give it a new object representing the new state.
如果我們給它一個表示新狀態的新對象,則可以使用this.setState()
更改狀態。
Our component on the page will always represent its current state. React does that for us.
頁面上的組件將始終代表其當前狀態。 React為我們做到了。
handleClick() { if (this.state.isMusicPlaying) { this.setState({ isMusicPlaying: false }); } else { this.setState({ isMusicPlaying: true }); } };
But clicking an h1
isn’t as good as clicking our actual play button. Let’s make that work.
但是單擊h1
不如單擊我們的實際播放按鈕那樣好。 讓我們開始吧。
組件之間的對話 (Talking Between Components)
Your components can talk to each other. Let’s try it.
您的組件可以互相通信。 讓我們嘗試一下。
We can tell PlayButton
whether or not the music is playing using something called props
. Props are information shared from a parent component to a child component.
我們可以使用props
來告訴PlayButton
音樂是否正在播放。 道具是從父組件共享到子組件的信息。
Props in JSX look the same as HTML properties.
JSX中的道具看起來與HTML屬性相同。
We give PlayButton
a prop called isMusicPlaying
, which is the same as the isMusicPlaying
in this.state
.
我們給PlayButton
一個道具叫isMusicPlaying
,這是一樣的isMusicPlaying
在this.state
。
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; }
handleClick() { if (this.state.isMusicPlaying) { this.setState({ isMusicPlaying: false }); } else { this.setState({ isMusicPlaying: true }); } };
render() { return ( <div> <PlayButton isMusicPlaying={this.state.isMusicPlaying} /> </div> ); }}
When the state of Container
changes, PlayButton
prop will change too, and the PlayButton
function will be called again. That means our component will update on the screen.
當Container
的狀態更改時, PlayButton
也將更改,并且PlayButton
函數將再次被調用。 這意味著我們的組件將在屏幕上更新。
Inside PlayButton
, we can react to the change, because PlayButton
gets the props as an argument:
在PlayButton
,我們可以對更改做出React,因為PlayButton
將props作為參數:
function PlayButton(props) { const className = props.isMusicPlaying ? 'play active' : 'play'; return <a href="#" title="Play video" className={className} />;}
If we change our state to this.state = { isMusicPlaying: true };
and reload the page, you should see the pause button:
如果我們將狀態更改為this.state = { isMusicPlaying: true };
并重新加載頁面,您應該看到“暫停”按鈕:
活動作為道具 (Events as Props)
Your props don’t have to be just information. They can be functions.
您的道具不必僅僅是信息。 它們可以是函數。
function PlayButton(props) { const className = props.isMusicPlaying ? 'play active' : 'play'; return <;a onClick={props.onClick} href="#" title="Play video" className={className} />;}
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; }
handleClick() { if (this.state.isMusicPlaying) { this.setState({ isMusicPlaying: false }); } else { this.setState({ isMusicPlaying: true }); } };
render() { return ( <div> <PlayButton onClick={this.handleClick.bind(this)} isMusicPlaying={this.state.isMusicPlaying} /> </div> ); }}
Now, when we click on the PlayButton
, it’ll change the state of Container
, which will change the props
of PlayButton
, which will cause it to update on the page.
現在,當我們單擊PlayButton
,它將更改Container
的狀態,這將更改PlayButton
的props
,這將使其在頁面上更新。
關于setState的壞事 (The Bad Thing About setState)
setState
is bad because it doesn’t do stuff right away. React waits a bit to see if there are more changes to make, then it does the state changes.
setState
不好,因為它不會立即做任何事情。 React稍等一下,看看是否還有更多更改要進行,然后它進行狀態更改。
That means you don’t know for sure what your state will be when you call setState
.
這意味著您不確定調用setState
時的狀態。
So you shouldn’t do this:
因此,您不應該這樣做:
handleClick() { this.setState({ isMusicPlaying: !this.state.isMusicPlaying });};
If you are changing your state based on the old state, you need to do things differently.
如果您要根據舊狀態更改狀態,則需要做不同的事情。
You need to give setState
a function, not an object. This function gets the old state as an argument, and returns an object that is the new state.
您需要給setState
一個函數,而不是一個對象。 此函數將舊狀態作為參數,并返回一個新狀態的對象。
It looks like this:
看起來像這樣:
handleClick() { this.setState(prevState => { return { isMusicPlaying: !prevState.isMusicPlaying }; });};
It is more difficult, but only needed when you are using the old state to make the new state. If not, you can just give setState
an object.
這比較困難,但是只有在使用舊狀態創建新狀態時才需要。 如果沒有,您可以給setState
一個對象。
什么是裁判? (What Are Refs?)
Let’s make some music happen.
讓我們做些音樂吧。
First, we add an <aud
io> tag:
首先,我們添加一個<aud
io>標簽:
class Container extends React.Component { constructor(props) { super(props); this.state = { isMusicPlaying: false }; }
handleClick() { this.setState(prevState => { return { isMusicPlaying: !prevState.isMusicPlaying }; }); };
render() { return ( <div> <PlayButton onClick={this.handleClick.bind(this)} isMusicPlaying={this.state.isMusicPlaying} /> <audio id="audio" /> </div> ); }}
We need a way to get that <aud
io> tag and call either
play() or p
ause() on it. We could do it with document.getElementById('audio').
play() but there’s a better React way.
我們需要一種方法來獲取<aud
IO>標簽和呼叫E ither
播放() or p
上澳洲英語()。 我們可以with document.getElementById('audio').
做到這一點with document.getElementById('audio').
play()但有更好的React方法。
We give it a prop called ref
, which gets called with the <aud
io> element as the first argument. It takes that &
lt;audio> element and assigns it t
o this.audio.
我們給它提供了一個名為ref
的道具,該道具以<aud
io>元素作為第一個參數被調用。 它that &
lt; audio>元素并將其作為this.audio的signs it t
。
<audio id="audio" ref={(audioTag) => { this.audio = audioTag }} />
This function will be called every time the Container
renders, which means this.audio
will always be up to date, and equal the <aud
io> tag.
每次Container
渲染時都會調用此函數,這意味著this.audio
將始終是最新的,并且等于<aud
io>標簽。
We then can play and pause the music:
然后,我們可以播放和暫停音樂:
handleClick() { if (this.state.isMusicPlaying) { this.audio.pause(); } else { this.audio.play(); } this.setState(prevState => { return { isMusicPlaying: !prevState.isMusicPlaying }; });};
Upload a music file (preferably an mp3 file) using the Choose files
button and hit play, and watch it go!
使用“ Choose files
按鈕上傳音樂文件(最好是mp3文件)并點擊播放,然后觀看吧!
移出Index.html (Moving Outside of Index.html)
As you might have guessed, our React shouldn’t live forever inside a <scri
pt>tag.
您可能已經猜到了,我們的React不應永遠存在于<scri
pt>標簽中。
React takes a lot of build configuration. Fortunately, tools like Create React App take care of all that for you.
React需要大量的構建配置。 幸運的是,諸如Create React App之類的工具可以為您完成所有工作。
Install it to create your own React project. Follow their brief tutorial and start editing the JavaScript inside the src
directory, applying all the React knowledge you learned here!
安裝它以創建自己的React項目。 遵循他們的簡短教程,并開始應用src
目錄中的所有React知識來編輯src
目錄中JavaScript!
恭喜你! (Congratulations!)
You can now make React things.
您現在可以制作React東西了。
Next, check out a couple of articles for more information. One is about React best practices, the other about a useful part of React called lifecycle methods.
接下來,查看幾篇文章以獲取更多信息。 一個是關于React最佳實踐的 ,另一個是關于React有用部分的生命周期方法 。
If you learned something from this article, please click those clappin’ hands, and share it with your friends.
如果您從本文中學到了一些知識,請單擊那些拍手的手,并將其分享給您的朋友。
You can also follow me on Medium and Twitter.
您也可以在Medium和Twitter上關注我。
翻譯自: https://www.freecodecamp.org/news/everything-you-need-to-know-about-react-eaedf53238c4/
react構建