發(fā)布于:2021-02-05 11:55:20
0
214
0
輔助項目和實際應(yīng)用對于程序員來說是非常令人著迷的術(shù)語,但是構(gòu)建輔助項目并不是小菜一碟,我們必須先構(gòu)建一些項目才能獲得一定的專業(yè)知識,然后再開始自己的項目。Freecodecamp在這方面非常有幫助。因此,今天我們將使用React解決freecodecamp的Random Quote Machine挑戰(zhàn)。
讓我們先計劃一下應(yīng)用程序
我們將這個小應(yīng)用程序分為兩個步驟。
在第一步中,我們將在單個組件中設(shè)計整個應(yīng)用程序。一旦它將實現(xiàn)的目的,我們將進入第二步,并將應(yīng)用程序分為小的獨立組件,這將是有益的,如果應(yīng)用程序在未來變得更大。
組件設(shè)置
在編寫任何邏輯之前,我們將設(shè)置組件,并用quote和author值初始化state對象。值暫時將是空字符串。
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請求包
我們將使用axios
進行API
請求。它基于承諾,使Api
請求更簡單、更簡短、更簡潔。
我們將在componentDidMount
生命周期方法中調(diào)用我們的API
。
你可能會想為什么?
所以在這里我們首先要明確一個概念,有些新手可能沒有意識到這一點。
概念
在我們基于類的組件中,我們有一些預(yù)定義的方法,每個方法都有特定的特性和執(zhí)行時間。
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在默認呈現(xiàn)方法之后運行。所以它是API調(diào)用的最佳場所。
componentDidMount() { this.getQuote() } getQuote() { let url = 'https://gist.githubusercontent.com/camperbot/5a022b72e96c4c9585c32bf6a75f62d9/raw/e3c6895ce42069f0ee7e991229064f167fe8ccdc/quotes.json' axios.get(url) .then(res => console.log(res)) }
如果我們檢查,我們可以看到控制臺中的API數(shù)據(jù)。這意味著我們成功地調(diào)用了API。
現(xiàn)在我們將用setState
屬性更改state對象,并使quote和author值等于我們從api獲得的一些數(shù)據(jù)。
是時候?qū)扅c邏輯了。
邏輯1:從API中隨機選擇一個報價
如果我們能找出如何從數(shù)組中得到一個隨機元素,我們就可以為此編寫邏輯。我們有一個引號數(shù)組,它作為一個元素進一步包含引號和作者鍵。
我們知道,為了在Javascript中獲得隨機數(shù),我們使用內(nèi)置的Math.random()
函數(shù),并且為了從特定長度獲得數(shù)據(jù),我們將像這樣擴展它
Math.floor(Math.random() * data.length)
Math.floor()只是將數(shù)字向下舍入到最接近的整數(shù)。
這將給我們從0到數(shù)組長度的隨機數(shù),我們將它存儲在變量quoteNum
中。
如果把quoteNum
當作一個索引怎么辦?我們將從引號數(shù)組中獲得一個隨機元素。
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
你會發(fā)現(xiàn),應(yīng)用程序運行后,你會在幾毫秒內(nèi)看不到數(shù)據(jù),因為從api獲取數(shù)據(jù)需要時間。
一旦請求成功,它將使用setState
在state
中存儲新值,我們的DOM
將用新數(shù)據(jù)更新。
造型
我們需要做三件事
設(shè)計背景
設(shè)計報價框
設(shè)計按鈕
這篇文章不是關(guān)于造型的。如果你什么都不懂,你可以在評論區(qū)問。
我已經(jīng)添加了媒體查詢,以便在小屏幕時做出響應(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; } }
我們完成了第一步。
讓我們來談?wù)剶U展應(yīng)用程序
記住,我們總是以一種更易于增長、閱讀和維護的方式來構(gòu)建我們的項目。
可重復(fù)使用的報價框
假設(shè)我們希望以后向應(yīng)用程序添加更多屏幕/路由,并且我們希望使用相同的報價框,但使用不同的文本/數(shù)據(jù)。因此,我們將為此制作一個單獨的組件報價箱。我們將使用新的報價和共享按鈕執(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> ) }
在這里,我們通過以下方式從RandomQuote組件獲取作者和報價值props.
可重復(fù)使用按鈕
假設(shè)這是一個客戶項目,他改變了主意,要求你不要有一個新的報價按鈕,他想有兩個按鈕,一個用于下一個報價,一個用于上一個報價。
因此,最好是制作一個可重復(fù)使用的按鈕,我們將在任何需要相同按鈕的地方使用按鈕組件。
//Button component const Button = ({ onClick, title }) => { return ( <button className='button' id='new-quote' onClick={onClick}>{title}</button> ) }
可重復(fù)使用的共享按鈕
如果我們以后想添加Facebook、Instagram和whatsapp共享怎么辦。他們將共享相同的樣式,但不同的props
。因此最好將其寫入一個單獨的文件中,這樣便于維護。
// 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> ) }
這就是我們的隨機報價類的樣子,現(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> ) } }
這篇文章有點長,希望你能跟著學點新東西。