到目前为止,在这个React系列中,我们已经创建了一个工作示例应用程序作为“ Movie Mojo”画廊应用程序的起点,并且我们已经看到了使用props如何允许我们通过传递数据而不是数据来自定义组件的外观。硬编码。

在第三部分中,我们将创建第一个自定义组件,然后将状态添加到我们的应用程序中。 这将使我们能够轻松管理应用程序数据,而不必担心手动更新DOM。 从现在开始,我们将看到如何让React处理所有DOM渲染。

一组四部电影将在页面加载时显示在我们的画廊中,单击“ 加载更多...”按钮时,还将加载并显示另外四部电影。

让我们首先解决添加<Movie />组件,该组件将显示有关单个电影的信息。

添加影片组件

<Movie />组件将显示有关单个电影的信息。 多个<Movie />组件将一起显示,以形成一些感觉良好的电影的电影库。 因此,我们的React应用的名称为“ Movie Mojo”!

在添加<Movie />组件之前,让我们更新App.jsCSS,以设置图库中各个电影的样式。 打开App.css并将样式替换为:

.App {text-align: center;
}.App-logo {animation: App-logo-spin infinite 20s linear;height: 80px;
}.App-header {background-color: steelblue;height: 70px;padding: 20px;color: white;
}.App-intro {font-size: large;
}/* new css for movie component */
* {box-sizing: border-box;
}.movies {display: flex;flex-wrap: wrap;
}.App-header h2 {margin: 0;
}.add-movies {text-align: center;
}.add-movies button {font-size: 16px;padding: 8px;margin: 0 10px 30px 10px;
}.movie {padding: 5px 25px 10px 25px;max-width: 25%;
}

这样可以对画廊进行样式设置,使其以网格形式显示电影,并改善其他视觉元素之间的间距。

另外,在/public/posters/ ,为了方便起见,我添加了12张电影海报,如果您遵循的话,可以在自己的项目中使用。 您可以在第4部分的完成的项目中下载它们。只需在posters文件夹中复制到您自己的React app public文件夹中即可。

您也可以从原始网站下载自己的电影海报。 在本教程中,我将cinematerial.com用于所有电影海报。 下载海报需要支付少量费用,但是如果您想在其他地方尝试,可能还有许多其他海报来源。

好,回到我们的<Movie />组件。 在/src/components/文件夹中,创建一个新的Movie.js文件,在编辑器中将其打开,然后添加以下内容:

import React, { Component } from 'react';class Movie extends Component {render() {return (<div className="movie"><h2>{ this.props.title }</h2><div><img width="200" src={ this.props.poster } /></div><p>({ this.props.year })</p><p>{ this.props.description }</p></div>);}
}export default Movie;

这与<Header />组件非常相似,除了我们引用的是多个道具而不仅仅是一个。 让我们使用<Movie />组件显示一些电影。

App.js<div>包装器内添加四个<Movie />组件,以便我们可以轻松地将样式仅应用于电影元素。 这是完整的App.js代码:

import React, { Component } from 'react';
import '../App.css';
import Header from './Header';
import Movie from './Movie';class App extends Component {render() {return (<div className="App"><Header text="Discover Your Movie Mojo!" /><p className="App-intro">Sharing a few of our favourite movies</p><div className="movies"><Movie title="50 First Dates" year="2004" description="Henry Roth is a man afraid of commitment up until he meets the beautiful Lucy. They hit it off and Henry think he's finally found the girl of his dreams." poster="./posters/50-first-dates.png" /><Movie title="Ferris Bueller's Day Off" year="1986" description="A high school wise guy is determined to have a day off from school, despite what the principal thinks of that." poster="./posters/ferris.png" /><Movie title="Matilda" year="1996" description="Story of a wonderful little girl, who happens to be a genius, and her wonderful teacher vs. the worst parents ever and the worst school principal imaginable." poster="./posters/matilda.png" /><Movie title="Dirty Dancing" year="1987" description="Spending the summer at a Catskills resort with her family, Frances 'Baby' Houseman falls in love with the camp's dance instructor, Johnny Castle." poster="./posters/dirty-dancing.png" /></div></div>);}
}export default App;

注意如何像<Header />一样显式导入<Movie />组件,以使其在代码中可用。 每个电影组件都实现了titleyeardescriptionposter道具。

结果是将四个<Movie />组件添加到我们的图库中。


App.js一次手动添加电影非常繁琐。 实际上,应用程序数据很可能来自数据库,并在添加到应用程序的状态对象之前临时存储在JSON对象中。

管理React状态

React应用程序的状态是什么? 您可以将其视为代表您应用程序中所有数据的单个JavaScript对象。 可以在任何组件上定义状态,但是如果要在组件之间共享状态,则最好在顶级组件上定义状态。 然后可以将状态传递给子组件,并根据需要进行访问。

即使状态是一个主要对象,该对象也可以包含与您的应用程序不同部分相关的多个子对象。 例如,在购物车应用程序中,您可能具有用于订单中商品的状态对象,以及用于监视库存的另一个对象。

在我们的“ Movie Mojo”应用程序中,我们只有一个子状态对象,用于将电影存储在我们的画廊中。

使用状态背后的核心思想是,只要您的应用程序中的数据发生更改,React就会为您更新DOM的相关部分。 您所需要做的就是管理应用程序中的数据或状态,然后React处理所有DOM更新。

通过州添加电影

为了简单起见,我们将放弃数据库步骤,并假设电影数据已从数据库中检索并以JSON格式存储。

为了演示将项目添加到初始状态以及在事件发生时(例如按下按钮)更新状态的方法,我们将使用两个JSON对象,每个对象包含有关四部电影的数据。

src文件夹中,添加一个新的movies.js文件,在编辑器中将其打开,然后添加以下代码来定义我们的两个JSON对象:

// some sample movies
const initialMovies = {movie1: {title: "Ferris Bueller's Day Off",year: "1986",description: "A high school wise guy is determined to have a day off from school, despite what the principal thinks of that.",poster: "./posters/ferris.png"},movie2: {title: "Bridget Jones' Diary",year: "2001",description: "A British woman is determined to improve herself while she looks for love in a year in which she keeps a personal diary.",poster: "./posters/bridget-jones.png"},movie3: {title: "50 First Dates",year: "2004",description: "Henry Roth is a man afraid of commitment up until he meets the beautiful Lucy. They hit it off and Henry think he's finally found the girl of his dreams.",poster: "./posters/50-first-dates.png"},movie4: {title: "Matilda",year: "1996",description: "Story of a wonderful little girl, who happens to be a genius, and her wonderful teacher vs. the worst parents ever and the worst school principal imaginable.",poster: "./posters/matilda.png"}
};const additionalMovies = {movie5: {title: "Dirty Dancing",year: "1987",description: "Spending the summer at a Catskills resort with her family, Frances 'Baby' Houseman falls in love with the camp's dance instructor, Johnny Castle.",poster: "./posters/dirty-dancing.png"},movie6: {title: "When Harry Met Sally",year: "1989",description: "Harry and Sally have known each other for years, and are very good friends, but they fear sex would ruin the friendship.",poster: "./posters/when-harry-met-sally.png"},movie7: {title: "Elf",year: "2003",description: "After inadvertently wreaking havoc on the elf community due to his ungainly size, a man raised as an elf at the North Pole is sent to the U.S. in search of his true identity.",poster: "./posters/elf.png"},movie8: {title: "Grease",year: "1978",description: "Good girl Sandy and greaser Danny fell in love over the summer. When they unexpectedly discover they're now in the same high school, will they be able to rekindle their romance?",poster: "./posters/grease.png"}
};export {initialMovies};
export {additionalMovies};

在我们的<App />组件中引用JSON对象之前,我们需要导入它们。 将其添加到App.js的顶部:

import {initialMovies} from '../movies';
import {additionalMovies} from '../movies';

每个JSON对象现在是通过变量可用initialMoviesadditionalMovies 。 不过,到目前为止,我们还没有与应用程序关联的任何状态。 让我们现在修复它。

“ Movie Mojo”应用程序中的顶级组件是<App /> ,所以让我们在此处添加状态对象。 我们需要与组件类一起初始化状态,这可以通过构造函数来完成。

在React类中使用构造函数时,您需要先调用super()因为我们要扩展的Component对象需要先初始化。 另外,在super()返回之前, this关键字在构造函数中不可用。

要初始化我们的state对象,请将其添加到<App />组件类中:

constructor() {super();this.state = {movies: {}};
}

这将为我们的React应用程序创建一个空状态对象。 使用React开发人员工具,我们可以看到state对象直接在<App />组件上初始化。


但是,我们想用一些电影初始化state对象,以便它们在页面加载时立即显示。 为此,我们可以使用initialMovies而不是空对象来初始化movies状态对象。

constructor() {super();this.state = {movies: initialMovies};
}

这会将我们的应用程序的初始状态设置为initialMovies JSON对象中存储的四部电影,但是图库中的电影仍通过前面添加的硬编码<Movie />组件进行显示。


我们需要在movie状态对象中输出电影,这可以通过使用循环遍历每个电影来完成。

首先,删除硬编码的<Movie />组件,然后将其替换为:

{Object.keys(this.state.movies).map(key => <Movie key={key} meta={this.state.movies[key]} />)
}

此代码需要一些解释。 movie状态对象包含存储为对象的各个电影,但是要遍历它们,可以更轻松地使用数组。

因此,我们使用Object.keys()来获取电影对象的所有键并将它们存储在数组中。 然后使用.map()进行迭代,并为movies状态对象中的每个电影输出<Movie />组件。

不过,与我们之前添加<Movie />方式相比,有一些更改。 首先,我们通过单个meta属性传递单个电影的所有信息。 实际上,这比以前更加方便,因为我们为每个电影属性都指定了一个单独的道具。

另外,请注意,我们也指定了一个key道具。 React内部使用它来跟踪循环添加的组件。 该组件实际上不可用,因此您不应该尝试用自己的代码访问它。

没有key道具,React会引发错误,因此包含它很重要。 React需要知道已添加,更新或删除了哪些新电影,以便可以使所有内容保持同步。

在显示组件之前,我们还需要做一件事。 打开Movie.js ,并为每个对道具的引用添加meta前缀,如下所示:

<div className="movie"><h2>{ this.props.meta.title }</h2><div><img width="200" src={ this.props.meta.poster } /></div><p>({ this.props.meta.year })</p><p>{ this.props.meta.description }</p>
</div>

加载更多电影

我们已经看到了如何显示在应用初始化时添加到状态的电影,但是如果我们想在某个时候更新电影库怎么办?

这就是React真正发挥作用的地方。 我们要做的就是更新movie状态对象中的movie ,React会自动更新应用程序中使用该对象的所有部分。 因此,如果我们添加一些电影,React将触发<App />组件的render()方法来更新我们的电影库。

让我们看看如何实现这一点。

首先在App.js的结束div包装器内添加HTML按钮。

<div className="add-movies"><button onClick={this.loadAdditionalMovies}>Load more...</button></div>

单击该按钮时,将调用类方法loadAdditionalMovies 。 将此方法添加到<App />组件类中:

loadAdditionalMovies() {var currentMovies = { ...this.state.movies };var newMovies = Object.assign( currentMovies, additionalMovies );this.setState({ movies: newMovies });
}

只要遵循推荐的方法,即将当前状态对象复制到新对象并使用新项目更新该副本,更新状态就相对简单。 然后,要设置新状态,我们调用this.setState并传入新的状态对象以覆盖前一个对象。 状态一经更新,React便仅更新DOM中受状态更改影响的部分。

loadAdditionalMovies()的第一行使用spread运算符将this.state.movies对象的所有属性复制到新的currentMovies对象中。

之后,我们使用Object.assign将两个对象合并在一起,从而将新电影列表添加到当前列表中。

loadAdditionalMovies()方法loadAdditionalMovies()之前,我们只需要完成一个步骤。 要引用任何自定义组件方法,我们首先需要手动将其绑定到组件类。

这是React的怪癖,只是您必须记住要做的事情。 任何时候在没有手动绑定的情况下访问方法时,React都会抱怨并抛出编译错误。

将此添加到App.js的类构造函数中:

this.loadAdditionalMovies = this.loadAdditionalMovies.bind(this);

只要你记得要使用此解决方法需要使用的每一个自定义的方法this ,你就不会遇到任何问题。

现在,尝试单击“ 加载更多...”按钮。 您应该会再看到四部电影添加到图库中。


这证明了React的关键优势。 也就是说,让您专注于应用程序中的数据,并将DOM的所有常规更新留给React。 要添加电影,我们要做的就是更新movie状态对象中的数据,React负责其他所有工作。

我们的示例应用程序仍然非常基础,但是请想象一个具有许多组件和多个状态对象的复杂得多的应用程序。 当您的应用程序中的数据发生更改时,尝试手动更新DOM将是一项巨大的任务(而且容易出错)!

结论

在本教程中,我们的“电影Mojo”应用确实取得了一些进步。 我们使用React状态来帮助管理应用程序中的电影列表。 当我们初始化应用程序时,我们不仅将影片添加到初始状态对象中,而且当单击“ 加载更多...”按钮时,我们还更新了图库中的影片列表。

在第四部分以及本系列的最后一篇教程中,我们将介绍如何通过自定义表单将电影手动添加到我们的画廊。 用户将能够填写该表格并添加有关电影的详细信息,该详细信息将被添加到图库中显示的电影列表中。

翻译自: https://code.tutsplus.com/tutorials/react-crash-course-for-beginners-part-3--cms-29293

针对初学者的React Crash课程,第3部分相关推荐

  1. 15个针对初学者的Python项目创意

    15个适合初学者的Python项目构想-在完成Python编程课程之后,每个初学者都应转向可帮助您发展编码技能的python项目.我知道您在想什么,我们是初学者,我们将如何完成这些python项目?今 ...

  2. pca针对初学者_针对初学者和专家的12酷数据科学项目创意

    pca针对初学者 The domain of Data Science brings with itself a variety of scientific tools, processes, alg ...

  3. react实战课程_在使用React一年后,我学到的最重要的课程

    react实战课程 by Tomas Eglinskas 由Tomas Eglinskas 在使用React一年后,我学到的最重要的课程 (The most important lessons I'v ...

  4. 组件分享之前端组件——初学者的web开发课程Web-Dev-For-Beginners

    组件分享之前端组件--初学者的web开发课程Web-Dev-For-Beginners 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题, ...

  5. 自学网的计算机基础视频,我要自学网-为零基础初学者提供计算机知识课程视频教学的自学平台...

    我要自学网是一款为零基础初学者提供计算机知识课程视频教学的自学APP,我要自学网APP主要提供的是计算机方面的知识课程,这些课程都是视频教学的,在我要自学网中用户可以学习到很多的计算机知识,APP中提 ...

  6. 初学者的React全家桶完整实例

    概述 该项目还有些功能在开发过程中,如果您有什么需求,欢迎您与我联系.我希望能够通过这个项目对React初学者,或者Babel/webpack初学者都有一定的帮助.我在此再强调一下,在我写的这些文章末 ...

  7. 渗透测试初学者_渗透测试许可证:面向初学者的道德黑客课程

    渗透测试初学者 A penetration test is an authorized cyberattack on a computer system, performed to evaluate ...

  8. 谷歌推出针对AI歧视的新课程!60分钟的ML公平自学训练模块 | 资源

    乾明 编译整理自 Google Blog  量子位 报道 | 公众号 QbitAI 有太多的AI都充满了歧视与偏见. 比如,亚马逊招聘AI歧视女性:谷歌的推荐系统偏向于给女性推送低薪广告等等. 针对这 ...

  9. 对初学者的React Hooks-关于useState和useEffect的大脑友好指南

    "What the heck are hooks?" "钩到底是什么?" I found myself asking this just as I though ...

最新文章

  1. Linux网络编程必看书籍推荐
  2. Java内存溢出的详细解决方案
  3. web安全_皮卡丘_xss
  4. h5日期选择控件_成都h5开发工程师培训_H5入门需要知道的知识
  5. stm32超声波扫频_基于STM32的脉冲式及扫频式超声波除垢信号源设计
  6. golang延时,在golang中使用延迟
  7. 企业网络信息安全意识宣贯——屏保制作
  8. Java调用Bing翻译
  9. 各纬度气候分布图_气候分布图有纬度
  10. 【小游戏】AB猜数字
  11. 谷歌Google搜索语法
  12. Windows特殊字符
  13. 给WordPress加个评论关闭时间提示
  14. 音乐计算机研修心得,音乐学习心得体会五篇
  15. 证明厄米矩阵不同特征值对应特征向量正交
  16. 高数笔记(十九):对面积的曲面积分,对坐标的曲面积分,高斯公式,斯托克斯公式
  17. 回顾 深度学习 实验三 线性回归
  18. 分布式消息队列基础知识
  19. 面试时如何用英语自我介绍?
  20. 《互联网+流通——F2R助力传统产业创新与转型》一一1.1 “互联网+”的本质、演进与发展趋势...

热门文章

  1. php 获取当前域名大胡子,养黄金大胡子的小经验
  2. 手机号码、电子邮箱、身份证、银行卡正则验证
  3. 不同的经络,不同的线程
  4. 常见软件环境的配置、下载...
  5. 尝试用visio画个等边三角形
  6. Java 集合之TreeSet 自定义类 比较器
  7. 平行四边形的效果实现
  8. android手机获取手机设备信息
  9. DONT_UNCOMPRESS_PRIV_APPS_DEXS配置
  10. 链接的接口——符号(一)链接错误:symbol lookup error: xxx, undefined symbol: xxx