在React教程的今天翻译中,我们将讨论组件属性。 这是该库中反映的最重要的概念之一。

→
第1部分:课程概述,React,ReactDOM和JSX普及的原因→
第2部分:功能组件→
第3部分:组件文件,项目结构→
第4部分:父级和子级组件→
第5部分:TODO应用程序的开始工作,样式设计的基础→
第6部分:关于本课程的一些功能,JSX和JavaScript→
第7部分:内联样式→
第8部分:继续研究TODO应用程序,熟悉组件的属性→
第9部分:组件属性→
第10部分:使用组件特性和样式的研讨会→
第11部分:动态标记生成和映射数组方法→
第12部分:研讨会,TODO应用程序的第三阶段工作→
第13部分:基于类的组件→
第14部分:关于基于类的组件,组件状态的研讨会→
第15部分:组件健康研讨会→
第16部分:TODO应用程序的第四阶段工作,事件处理→
第17部分:TODO应用程序的第五阶段工作,修改组件的状态→
第18部分:TODO应用程序的第六阶段工作→
第19部分:组件生命周期方法第20部分:条件渲染的第一课→
第21部分:关于条件渲染的第二课和研讨会→
第22部分:TODO应用程序的第七阶段工作,从外部资源下载数据→
第23部分:关于使用表格的第一课→
第24部分:第二形式课→
第25部分:使用表单的研讨会→
第26部分:应用程序体系结构,容器/组件模式→
第27部分:课程项目第19课。React中的组件属性
→
原创使用
create-react-app
创建一个新项目,并从
src
文件夹中更改几个标准文件的代码。
这是
index.js
文件的代码:
import React from "react" import ReactDOM from "react-dom" import "./index.css" import App from "./App" ReactDOM.render(<App />, document.getElementById("root"))
以下是
index.css
文件中描述的样式:
body { margin: 0; } .contacts { display: flex; flex-wrap: wrap; } .contact-card { flex-basis: 250px; margin: 20px; } .contact-card > img { width: 100%; height: auto; } .contact-card > h3 { text-align: center; } .contact-card > p { font-size: 12px; }
这是在
App.js
文件中找到的代码:
import React from "react" function App() { return ( <div className="contacts"> <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/200"/> <h3><font color="#3AC1EF">▍Fluffykins</font></h3> <p>Phone: (212) 555-2345</p> <p>Email: fluff@me.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/300"/> <h3><font color="#3AC1EF">▍Destroyer</font></h3> <p>Phone: (212) 555-3456</p> <p>Email: ofworlds@yahoo.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/200/100"/> <h3><font color="#3AC1EF">▍Felix</font></h3> <p>Phone: (212) 555-4567</p> <p>Email: thecat@hotmail.com</p> </div> </div> ) } export default App
这是该应用在浏览器中的外观。
浏览器中的应用程序页面在分析了应用程序的代码和外观之后,我们可以得出结论,使用特殊的组件来显示带有动物信息的卡片会很好。 现在,这些元素是通过
App
组件形成的。 考虑到我们在之前的课程中所讨论的内容,您可以走得更远-考虑可以通过向其传递属性或属性来定制的通用组件。
在我们的应用程序中,有一些卡片,上面印有猫的图像,它们的名称以及所有者(或他们自己)的联系信息-电话和电子邮件地址。 为了创建以后将成为所有此类卡的基础的组件,您可以采用
App
组件返回的标记片段之一。 例如-这:
<div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div>
App返回四个这样的块,每个块可用于创建独立的组件,但是这种方法不适合我们。 因此,我们将创建一个组件,该组件将成为应用程序显示的所有卡片的基础。 为此,请在
src
文件夹
ContactCard.js
创建一个新的组件文件,并在其中放入一个代码,该代码返回
App
组件返回的第一个
<div>
元素,其代码已在上面给出。 这是
ContactCard
组件的代码:
import React from "react" function ContactCard() { return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
显然,如果您创建此组件的多个实例,则所有这些实例都将包含相同的数据,因为此数据是硬编码在组件代码中的。 我们希望在创建此组件的不同实例时,可以自定义其显示的数据。 关键是可以向组件传递某些属性,然后他可以使用这些属性。
我们使用的功能组件是普通的JS函数,由于React库,在其中可以使用特殊的构造。 如您所知,尽管函数可以不带参数使用,但它们可以带参数。 我们的
ContactCard
组件的
ContactCard
现在已经存在)可以是一个简单的函数,无需接受任何内容,只需返回两个数字的和即可:
function addNumbers() { return 1 + 1 }
它可以用来找出数字1和1的总和,但是,例如,要使用不接受任何输入的函数将数字1和2相加,我们将不得不编写一个新函数。 很明显,如果您需要添加不同的数字,这种方法会带来极大的不便,因此在这种情况下,创建一个通用函数来添加数字是明智的选择,该函数需要两个数字并返回它们的和:
function addNumbers(a, b) { return a + b }
这样的函数返回什么取决于调用时传递给它的参数。 通过创建React组件,我们可以完全一样地进行。
我们将
App.js
组件
ContactCard
并返回其四个实例,而无需立即删除构成应用程序页面上卡片的代码:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard /> <ContactCard /> <ContactCard /> <ContactCard /> <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/200"/> <h3><font color="#3AC1EF">▍Fluffykins</font></h3> <p>Phone: (212) 555-2345</p> <p>Email: fluff@me.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/400/300"/> <h3><font color="#3AC1EF">▍Destroyer</font></h3> <p>Phone: (212) 555-3456</p> <p>Email: ofworlds@yahoo.com</p> </div> <div className="contact-card"> <img align="center" src="http://placekitten.com/200/100"/> <h3><font color="#3AC1EF">▍Felix</font></h3> <p>Phone: (212) 555-4567</p> <p>Email: thecat@hotmail.com</p> </div> </div> ) } export default App
现在,让我们研究用于实例化
ContactCard
组件的代码。 通过创建常规的HTML元素,我们可以自定义影响其行为和外观的属性。 这些属性的名称由标准硬编码。 对于组件,您可以使用完全相同的方法,唯一的区别是我们自己发明了属性的名称,并自行决定如何在组件代码中使用它们。
每个卡包含四个信息,每个卡可以更改这些信息。 这是猫和猫的名字以及电话和电子邮件地址的图像。 让猫的名字包含在
name
属性中,
imgURL
属性中的图像地址,
imgURL
属性中的
phone
以及
email
属性中的电子邮件地址。
我们将这些属性设置为
ContactCard
组件的实例,并且当我们从
App
已有的代码传输数据时,我们将删除其相应的片段。 结果,
App
组件的代码将如下所示:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard name="Mr. Whiskerson" imgUrl="http://placekitten.com/300/200" phone="(212) 555-1234" email="mr.whiskaz@catnap.meow" /> <ContactCard name="Fluffykins" imgUrl="http://placekitten.com/400/200" phone="(212) 555-2345" email="fluff@me.com" /> <ContactCard name="Destroyer" imgUrl="http://placekitten.com/400/300" phone="(212) 555-3456" email="ofworlds@yahoo.com" /> <ContactCard name="Felix" imgUrl="http://placekitten.com/200/100" phone="(212) 555-4567" email="thecat@hotmail.com" /> </div> ) } export default App
的确,仅将属性转移到组件不足以在组件中使用它们。 该页面将由上述
App
组件构成,将包含四张相同的卡,其数据已在
ContactCard
组件的代码中设置,但尚不知道如何处理传递给它的属性。
卡数据已硬编码在代码中;该组件无法使用传递给它的属性因此,现在该谈谈
ContactCard
组件如何与实例化时传递给它的属性一起使用。
我们通过在声明
ContactCard
函数时指出它接受
props
参数来解决此问题。 在这种情况下,组件代码将如下所示:
import React from "react" function ContactCard(props) { return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
实际上,该参数可以随意命名,但是在React中,习惯上将其称为
props
,而我们在这里谈论的属性通常简称为“ props”。
props
参数是一个对象。 该对象的属性是实例化组件时传递给组件的属性。 也就是说,例如,在我们的
props
对象中
props
将有一个
props.name
属性,
props.name
包含在实例化时传递给组件的cat的名称。 此外,它将具有属性
props.imgUrl
,
props.phone
,
props.email
。 要验证这一点,请在
ContactCard
函数的开头添加
console.log(props)
命令。
import React from "react" function ContactCard(props) { console.log(props) return ( <div className="contact-card"> <img align="center" src="http://placekitten.com/300/200"/> <h3><font color="#3AC1EF">▍Mr. Whiskerson</font></h3> <p>Phone: (212) 555-1234</p> <p>Email: mr.whiskaz@catnap.meow</p> </div> ) } export default ContactCard
这会将组件接收到的
props
对象带到控制台。
控制台道具对象在这里,您可以看到
ContactCard.js
中四个对象的输出。 它们之所以太多,是因为我们创建了
ContactCard
组件的四个实例。
所有这些使我们有机会在组件代码中使用而不是硬编码的值,而是在创建其实例时传递给它的内容,这些
props
可以以
props
对象
props
的形式获得。
如果我们尝试
props.imgUrl
这样使用
props.imgUrl
属性,该
props.imgUrl
:
<img align="center" src=props.imgUrl/>
乍一看,这种构造可能有效,但请记住,这里我们需要在JSX代码中使用JavaScript中的实体。 我们在上一课中讨论了如何完成此操作。 也就是说,在我们的例子中,对象的属性必须用大括号括起来:
<img align="center" src={props.imgUrl}/>
我们以相同的方式处理组件返回的其他元素,之后其代码将采用以下形式:
import React from "react" function ContactCard(props) { return ( <div className="contact-card"> <img align="center" src={props.imgUrl}/> <h3><font color="#3AC1EF">▍{props.name}</font></h3> <p>Phone: {props.phone}</p> <p>Email: {props.email}</p> </div> ) } export default ContactCard
请注意,在用于显示电话和电子邮件地址的字段中,我们在文本“
Phone:
和“
Email:
后面留有空格,因为这些文本在所有组件中均使用。 如果现在查看应用程序页面,您会注意到它包含四个不同的卡。
使用通用组件形成的页面我们的组件仅接受四个属性。 如果某个组件需要传递例如50个属性该怎么办? 就像在
App
组件中那样,将每个这样的属性作为单独的一行传递可能会很不方便。 在这种情况下,可以使用另一种方式将属性传输到组件。 它包含以下事实:创建组件的实例时,它不会传递属性列表,而是传递具有属性的对象。 这是第一个组件示例的外观:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard contact={{ name: "Mr. Whiskerson", imgUrl: "http://placekitten.com/300/200", phone: "(212) 555-1234", email: "mr.whiskaz@catnap.meow" }} /> <ContactCard name="Fluffykins" imgUrl="http://placekitten.com/400/200" phone="(212) 555-2345" email="fluff@me.com" /> <ContactCard name="Destroyer" imgUrl="http://placekitten.com/400/300" phone="(212) 555-3456" email="ofworlds@yahoo.com" /> <ContactCard name="Felix" imgUrl="http://placekitten.com/200/100" phone="(212) 555-4567" email="thecat@hotmail.com" /> </div> ) } export default App
这并不是说这种方法大大减少了用于描述组件实例的代码量。 事实是,尽管我们仅将一个组件传递给组件,但是传递给组件的属性仍然在代码中进行了硬编码。 在从某些外部源获取组件数据的情况下,可以感受到这种方法的优势。 例如,来自JSON文件。
在修改用于创建
ContactCard
组件的第一个实例的
App
组件的代码期间,该
App
的正确操作被中断。 这就是他的页面现在的样子。
应用程序故障如何解决? 为了理解这一点,使用
console.log(props)
分析正在发生的事情将很有用。
道具对象分析如您所见,第一个组件的
props
对象与第二个和下一个组件的相同对象不同。
在
ContactCard
组件中
ContactCard
我们基于
props
对象具有
name
,
imgUrl
和其他属性的假设来使用。 在这里,第一个组件仅接收一个属性
contact
。 这导致了一个事实,即
props
对象只有一个属性
contact
,它是对象,并且组件代码不提供这种结构的工作。
将我们的组件转换为仅使用包含其他属性的
contact
对象的一个属性的模型非常简单。 为此,例如,要访问
name
属性,
props.contact.name
在组件代码中使用
props.contact.name
形式的构造
props.contact.name
。 类似的设计使我们可以与我们需要的其他属性一起正常工作。
让我们回收组件代码,并考虑到包含其他属性的单个属性-对象
contact
的转移:
import React from "react" function ContactCard(props) { console.log(props) return ( <div className="contact-card"> <img align="center" src={props.contact.imgUrl}/> <h3><font color="#3AC1EF">▍{props.contact.name}</font></h3> <p>Phone: {props.contact.phone}</p> <p>Email: {props.contact.email}</p> </div> ) } export default ContactCard
现在应该可以正常显示第一个组件,但是在项目的此阶段我们将看不到该组件,因为系统会通知我们许多错误,这些错误与以下事实有关:在
App
组件中创建的
ContactCard
组件的多个实例未接收到以下属性:
contact
对象。 执行代码时,此属性为
undefined
。 结果,尝试引用
undefined
值的某个属性,这会导致错误。 我们将通过处理负责形成
ContactCard
组件的
App
组件的代码来解决此问题:
import React from "react" import ContactCard from "./ContactCard" function App() { return ( <div className="contacts"> <ContactCard contact={{ name: "Mr. Whiskerson", imgUrl: "http://placekitten.com/300/200", phone: "(212) 555-1234", email: "mr.whiskaz@catnap.meow" }} /> <ContactCard contact={{ name: "Fluffykins", imgUrl: "http://placekitten.com/400/200", phone: "(212) 555-2345", email: "fluff@me.com" }} /> <ContactCard contact={{ name: "Destroyer", imgUrl: "http://placekitten.com/400/300", phone: "(212) 555-3456", email: "ofworlds@yahoo.com" }} /> <ContactCard contact={{ name: "Felix", imgUrl: "http://placekitten.com/200/100", phone: "(212) 555-4567", email: "thecat@hotmail.com" }} /> </div> ) } export default App
现在,应用程序页面将与以前相同。
像往常一样,建议您尝试使用今天学到的概念,以便更好地理解它们。 例如,您可以使用代码,添加传递给组件的新属性,然后尝试在组件中使用它们。
总结
今天,我们介绍了可以传递给React组件以控制其行为和外观的属性的概念。 这些属性类似于HTML元素的属性,但是,程序员使用组件中的属性,可以独立地决定它们的含义以及组件中的确切含义。 下次,您将获得有关使用组件属性和样式的实践课程。
亲爱的读者们! 为了更好地理解React组件的属性,您如何尝试使用今天示例的代码?