發(fā)布于:2021-02-05 11:55:20
0
271
0
輔助項(xiàng)目和實(shí)際應(yīng)用對(duì)于程序員來(lái)說(shuō)是非常令人著迷的術(shù)語(yǔ),但是構(gòu)建輔助項(xiàng)目并不是小菜一碟,我們必須先構(gòu)建一些項(xiàng)目才能獲得一定的專業(yè)知識(shí),然后再開(kāi)始自己的項(xiàng)目。Freecodecamp在這方面非常有幫助。因此,今天我們將使用React解決freecodecamp的Random Quote Machine挑戰(zhàn)。
讓我們先計(jì)劃一下應(yīng)用程序
我們將這個(gè)小應(yīng)用程序分為兩個(gè)步驟。
在第一步中,我們將在單個(gè)組件中設(shè)計(jì)整個(gè)應(yīng)用程序。一旦它將實(shí)現(xiàn)的目的,我們將進(jìn)入第二步,并將應(yīng)用程序分為小的獨(dú)立組件,這將是有益的,如果應(yīng)用程序在未來(lái)變得更大。
組件設(shè)置
在編寫(xiě)任何邏輯之前,我們將設(shè)置組件,并用quote和author值初始化state對(duì)象。值暫時(shí)將是空字符串。
import React, { Component } from 'react' class RandomQuote extends Component { constructor(props) { super(props) this.state = { quote: '', //for quote author: '' //for author } } render() { return ( <div id='wrapper'> <h1 className='title'>Random Quote App</h1> </div> ) } } export default RandomQuote
API請(qǐng)求包
我們將使用axios
進(jìn)行API
請(qǐng)求。它基于承諾,使Api
請(qǐng)求更簡(jiǎn)單、更簡(jiǎn)短、更簡(jiǎn)潔。
我們將在componentDidMount
生命周期方法中調(diào)用我們的API
。
你可能會(huì)想為什么?
所以在這里我們首先要明確一個(gè)概念,有些新手可能沒(méi)有意識(shí)到這一點(diǎn)。
概念
在我們基于類的組件中,我們有一些預(yù)定義的方法,每個(gè)方法都有特定的特性和執(zhí)行時(shí)間。
import React, { Component } from 'react'; class App extends Component { constructor(props) { super(props) console.log('constructor runs') } componentDidMount() { console.log('componentDidMount runs') } render() { console.log('render method runs') return ( <div> <h1>Hello</h1> </div> ); } } export default App;
在componentDidMount中調(diào)用API
所以我們看到componentDidMount在默認(rèn)呈現(xiàn)方法之后運(yùn)行。所以它是API調(diào)用的最佳場(chǎng)所。
componentDidMount() { this.getQuote() } getQuote() { let url = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json' axios.get(url) .then(res => console.log(res)) }
如果我們檢查,我們可以看到控制臺(tái)中的API數(shù)據(jù)。這意味著我們成功地調(diào)用了API。
現(xiàn)在我們將用setState
屬性更改state對(duì)象,并使quote和author值等于我們從api獲得的一些數(shù)據(jù)。
是時(shí)候?qū)扅c(diǎn)邏輯了。
邏輯1:從API中隨機(jī)選擇一個(gè)報(bào)價(jià)
如果我們能找出如何從數(shù)組中得到一個(gè)隨機(jī)元素,我們就可以為此編寫(xiě)邏輯。我們有一個(gè)引號(hào)數(shù)組,它作為一個(gè)元素進(jìn)一步包含引號(hào)和作者鍵。
我們知道,為了在Javascript中獲得隨機(jī)數(shù),我們使用內(nèi)置的Math.random()
函數(shù),并且為了從特定長(zhǎng)度獲得數(shù)據(jù),我們將像這樣擴(kuò)展它
Math.floor(Math.random() * data.length)
Math.floor()只是將數(shù)字向下舍入到最接近的整數(shù)。
這將給我們從0到數(shù)組長(zhǎng)度的隨機(jī)數(shù),我們將它存儲(chǔ)在變量quoteNum
中。
如果把quoteNum
當(dāng)作一個(gè)索引怎么辦?我們將從引號(hào)數(shù)組中獲得一個(gè)隨機(jī)元素。
import React, { Component } from 'react' import axios from 'axios' class RandomQuote extends Component { constructor(props) { super(props) this.state = { quote: '', author: '' } } componentDidMount() { this.getQuote() } getQuote() { let url = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json' axios.get(url) .then(res => { let data = res.data.quotes let quoteNum = Math.floor(Math.random() * data.length) //quote number let randomQuote = data[quoteNum] //actual quote this.setState({ quote: randomQuote['quote'], author: randomQuote['author'] }) }) } getNewQuote = () => { this.getQuote() } render() { const { quote, author } = this.state return ( <div id='wrapper'> <h1 className='title'>Random Quote App</h1> <div id='quote-box'> <div id='text'><p>{quote}</p></div> <div id='author'><h5>{author}</h5></div> </div> </div> ) } } export default RandomQuote
你會(huì)發(fā)現(xiàn),應(yīng)用程序運(yùn)行后,你會(huì)在幾毫秒內(nèi)看不到數(shù)據(jù),因?yàn)閺腶pi獲取數(shù)據(jù)需要時(shí)間。
一旦請(qǐng)求成功,它將使用setState
在state
中存儲(chǔ)新值,我們的DOM
將用新數(shù)據(jù)更新。
造型
我們需要做三件事
設(shè)計(jì)背景
設(shè)計(jì)報(bào)價(jià)框
設(shè)計(jì)按鈕
這篇文章不是關(guān)于造型的。如果你什么都不懂,你可以在評(píng)論區(qū)問(wèn)。
我已經(jīng)添加了媒體查詢,以便在小屏幕時(shí)做出響應(yīng)。
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans|K2D'); body { background: linear-gradient(90deg, lightgreen, lightblue); font-family: 'K2D', sans-serif; display: flex; justify-content: center; align-items: center; height: calc(100vh - 100px); overflow-y: hidden; } .title { text-align: center; font-weight: 500; } #quote-box { width: 400px; margin: 0 auto; padding: 1px 15px; font-weight: 550; font-size: 22px; background: linear-gradient(35deg, #CCFFFF, #FFCCCC); text-align: center; border-radius: 20px; box-shadow: 0px 0px 2px 1px gray; } #text p { margin-block-start: 0.5em; margin-block-end: 0.5em; } #author h5 { margin-block-start: 1em; margin-block-end: 1em; } #buttons { display: flex; justify-content: space-between; } .twitter-icon { color: #1DA1F2 } .button { font-family: 'K2D', sans-serif; font-weight: 500; font-size: 1rem; padding: 5px; border-radius: 50em; box-shadow: 0px 0px 3px .5px rgb(82, 81, 81); border: 0; margin-bottom: 10px; } .button:focus { outline: none; border: none; } @media only screen and (max-width: 450px) { .title { font-size: 22px; } #quote-box { width: 270px; } }
我們完成了第一步。
讓我們來(lái)談?wù)剶U(kuò)展應(yīng)用程序
記住,我們總是以一種更易于增長(zhǎng)、閱讀和維護(hù)的方式來(lái)構(gòu)建我們的項(xiàng)目。
可重復(fù)使用的報(bào)價(jià)框
假設(shè)我們希望以后向應(yīng)用程序添加更多屏幕/路由,并且我們希望使用相同的報(bào)價(jià)框,但使用不同的文本/數(shù)據(jù)。因此,我們將為此制作一個(gè)單獨(dú)的組件報(bào)價(jià)箱。我們將使用新的報(bào)價(jià)和共享按鈕執(zhí)行類似的操作。
// Quote Box component const QuoteBox = ({ quote, author }) => { //destructuring return ( <React.Fragment> <div id='text'><p>{quote}</p></div> <div id='author'><h5>{author}</h5></div> </React.Fragment> ) }
在這里,我們通過(guò)以下方式從RandomQuote組件獲取作者和報(bào)價(jià)值props.
可重復(fù)使用按鈕
假設(shè)這是一個(gè)客戶項(xiàng)目,他改變了主意,要求你不要有一個(gè)新的報(bào)價(jià)按鈕,他想有兩個(gè)按鈕,一個(gè)用于下一個(gè)報(bào)價(jià),一個(gè)用于上一個(gè)報(bào)價(jià)。
因此,最好是制作一個(gè)可重復(fù)使用的按鈕,我們將在任何需要相同按鈕的地方使用按鈕組件。
//Button component const Button = ({ onClick, title }) => { return ( <button className='button' id='new-quote' onClick={onClick}>{title}</button> ) }
可重復(fù)使用的共享按鈕
如果我們以后想添加Facebook、Instagram和whatsapp共享怎么辦。他們將共享相同的樣式,但不同的props
。因此最好將其寫(xiě)入一個(gè)單獨(dú)的文件中,這樣便于維護(hù)。
// Social Share component const TwitterShare = ({ quote, author }) => { return ( <React.Fragment> <a href={`https://twitter.com/intent/tweet?text= ${quote} ${author}`} target="_blank" title="Post this quote on twitter!" id='tweet-quote'> <i className="fab fa-twitter twitter-icon" /> </a> </React.Fragment> ) }
這就是我們的隨機(jī)報(bào)價(jià)類的樣子,現(xiàn)在不是更干凈了嗎?
class RandomQuote extends Component { constructor(props) { super(props) this.state = { quote: '', author: '' } } componentDidMount() { this.getQuote() } getQuote() { let url = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json' axios.get(url) .then(res => { let data = res.data.quotes let quoteNum = Math.floor(Math.random() * data.length) let randomQuote = data[quoteNum] this.setState({ quote: randomQuote['quote'], author: randomQuote['author'] }) }) } getNewQuote = () => { //will be called on clicking the New Quote button this.getQuote() } render() { const { quote, author } = this.state return ( <div id='wrapper'> <h1 className='title'>Random Quote App</h1> <div id='quote-box'> <QuoteBox quote={quote} author={author} /> //passing data via props to QuoteBox component <div id='buttons'> <TwitterShare quote={quote} author={author} /> <Button id='new-quote' title='New Quote' onClick={this.getNewQuote} /> </div> </div> </div> ) } }
這篇文章有點(diǎn)長(zhǎng),希望你能跟著學(xué)點(diǎn)新東西。
作者介紹
熱門(mén)博客推薦