发布于:2021-02-05 11:55:20
0
113
0
辅助项目和实际应用对于程序员来说是非常令人着迷的术语,但是构建辅助项目并不是小菜一碟,我们必须先构建一些项目才能获得一定的专业知识,然后再开始自己的项目。Freecodecamp在这方面非常有帮助。因此,今天我们将使用React解决freecodecamp的Random Quote Machine挑战。
让我们先计划一下应用程序
我们将这个小应用程序分为两个步骤。
在第一步中,我们将在单个组件中设计整个应用程序。一旦它将实现的目的,我们将进入第二步,并将应用程序分为小的独立组件,这将是有益的,如果应用程序在未来变得更大。
组件设置
在编写任何逻辑之前,我们将设置组件,并用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
生命周期方法中调用我们的API
。
你可能会想为什么?
所以在这里我们首先要明确一个概念,有些新手可能没有意识到这一点。
概念
在我们基于类的组件中,我们有一些预定义的方法,每个方法都有特定的特性和执行时间。
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中调用API
所以我们看到componentDidMount在默认呈现方法之后运行。所以它是API调用的最佳场所。
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数据。这意味着我们成功地调用了API。
现在我们将用setState
属性更改state对象,并使quote和author值等于我们从api获得的一些数据。
是时候写点逻辑了。
逻辑1:从API中随机选择一个报价
如果我们能找出如何从数组中得到一个随机元素,我们就可以为此编写逻辑。我们有一个引号数组,它作为一个元素进一步包含引号和作者键。
我们知道,为了在Javascript中获得随机数,我们使用内置的Math.random()
函数,并且为了从特定长度获得数据,我们将像这样扩展它
Math.floor(Math.random() * data.length)
Math.floor()只是将数字向下舍入到最接近的整数。
这将给我们从0到数组长度的随机数,我们将它存储在变量quoteNum
中。
如果把quoteNum
当作一个索引怎么办?我们将从引号数组中获得一个随机元素。
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
你会发现,应用程序运行后,你会在几毫秒内看不到数据,因为从api获取数据需要时间。
一旦请求成功,它将使用setState
在state
中存储新值,我们的DOM
将用新数据更新。
造型
我们需要做三件事
设计背景
设计报价框
设计按钮
这篇文章不是关于造型的。如果你什么都不懂,你可以在评论区问。
我已经添加了媒体查询,以便在小屏幕时做出响应。
@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; } }
我们完成了第一步。
让我们来谈谈扩展应用程序
记住,我们总是以一种更易于增长、阅读和维护的方式来构建我们的项目。
可重复使用的报价框
假设我们希望以后向应用程序添加更多屏幕/路由,并且我们希望使用相同的报价框,但使用不同的文本/数据。因此,我们将为此制作一个单独的组件报价箱。我们将使用新的报价和共享按钮执行类似的操作。
// 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.
可重复使用按钮
假设这是一个客户项目,他改变了主意,要求你不要有一个新的报价按钮,他想有两个按钮,一个用于下一个报价,一个用于上一个报价。
因此,最好是制作一个可重复使用的按钮,我们将在任何需要相同按钮的地方使用按钮组件。
//Button component const Button = ({ onClick, title }) => { return ( <button className='button' id='new-quote' onClick={onClick}>{title}</button> ) }
可重复使用的共享按钮
如果我们以后想添加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> ) }
这就是我们的随机报价类的样子,现在不是更干净了吗?
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> ) } }
这篇文章有点长,希望你能跟着学点新东西。
作者介绍