初始代码(点击展开)
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
const pizzaData = [
{
name: "Focaccia",
ingredients: "Bread with italian olive oil and rosemary",
price: 6,
photoName: "pizzas/focaccia.jpg",
soldOut: false,
},
{
name: "Pizza Margherita",
ingredients: "Tomato and mozarella",
price: 10,
photoName: "pizzas/margherita.jpg",
soldOut: false,
},
{
name: "Pizza Spinaci",
ingredients: "Tomato, mozarella, spinach, and ricotta cheese",
price: 12,
photoName: "pizzas/spinaci.jpg",
soldOut: false,
},
{
name: "Pizza Funghi",
ingredients: "Tomato, mozarella, mushrooms, and onion",
price: 12,
photoName: "pizzas/funghi.jpg",
soldOut: false,
},
{
name: "Pizza Salamino",
ingredients: "Tomato, mozarella, and pepperoni",
price: 15,
photoName: "pizzas/salamino.jpg",
soldOut: true,
},
{
name: "Pizza Prosciutto",
ingredients: "Tomato, mozarella, ham, aragula, and burrata cheese",
price: 18,
photoName: "pizzas/prosciutto.jpg",
soldOut: false,
},
];
function App() {
return (
<div className="container">
<Header />
<Menu />
<Footer />
</div>
);
}
function Header() {
const style = {};
return (
<header className="header">
<h1 style={style}>Fast React Pizza Co.</h1>
</header>
);
}
function Menu() {
const pizzas = pizzaData;
// const pizzas = [];
const numPizzas = pizzas.length;
return (
<main className="menu">
<h2>Our Menu</h2>
{numPizzas > 0 ? (
<>
<p>我们提供多种美味的比萨选择,全部使用新鲜原料制作。</p>
<ul className="pizzas">
{pizzas.map((pizza) => (
<Pizza pizzaObj={pizza} key={pizza.name} />
))}
</ul>
</>
) : (
<p>We're still working on our menu. Please come back later</p>
)}
{/* <Pizza
name="Pizza Spinaci"
ingredient="Tomato, mozarella, spinach, and ricotta cheese"
photoName="pizzas/spinaci.jpg"
price={10}
/>
<Pizza
name="Pizza Funghi"
ingredient="Tomato, mushrooms"
price={12}
photoName="pizzas/funghi.jpg"
/> */}
</main>
);
}
function Pizza(props) {
console.log(props);
if (props.pizzaObj.soldOut) {
return null;
}
return (
<li className="pizza">
<img src={props.pizzaObj.photoName} alt={props.pizzaObj.name}></img>
<div>
<h3>{props.pizzaObj.name}</h3>
<p>{props.pizzaObj.ingredients}</p>
<span>{props.pizzaObj.price}</span>
</div>
</li>
);
}
function Footer() {
const hour = new Date().getHours();
const openHour = 20;
const closeHour = 22;
const isOpen = hour >= openHour && hour <= closeHour;
console.log(isOpen);
return (
<footer className="footer">
{isOpen ? (
<Order closeHour={closeHour} />
) : (
<p>
We're happy to welcome you between {openHour}:00 and {closeHour}
</p>
)}
</footer>
);
}
function Order(props) {
return (
<div className="order">
<p>
We're open until {props.closeHour}:00. Come visit us or order online.
</p>
<button className="btn">Order</button>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
在 React 中,每个组件都会自动接收一个 props 对象,即使我们没有显式传递任何属性。这个对象包含了所有传递给该组件的属性。 例如,在示例代码中的 Pizza 组件:
function Pizza(props) {
console.log(props);
if (props.pizzaObj.soldOut) {
return null;
}
return (
<li className="pizza">
<img src={props.pizzaObj.photoName} alt={props.pizzaObj.name}></img>
<div>
<h3>{props.pizzaObj.name}</h3>
<p>{props.pizzaObj.ingredients}</p>
<span>{props.pizzaObj.price}</span>
</div>
</li>
);
}这个组件接收一个props对象,并且需要通过 props.pizzaObj 来访问传入的披萨数据。
使用解构简化 Props 的使用
重复写 props. 前缀不仅冗长,还降低了代码的可读性。通过 JavaScript 的解构赋值,我们可以直接在函数参数中提取所需的属性:
function Pizza({ pizzaObj }) {
console.log(pizzaObj);
if (pizzaObj.soldOut) {
return null;
}
return (
<li className="pizza">
<img src={pizzaObj.photoName} alt={pizzaObj.name}></img>
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>{pizzaObj.price}</span>
</div>
</li>
);
}解构的两大优势
- 代码更简洁:不再需要重复写
props.前缀 - 自文档化:直接从函数定义就能看出组件接收什么属性
例如,对于 Order 组件:
// 修改前
function Order(props) {
return (
<div className="order">
<p>
We're open until {props.closeHour}:00. Come visit us or order online.
</p>
<button className="btn">Order</button>
</div>
);
}
// 修改后
function Order({ closeHour, openHour }) {
return (
<div className="order">
<p>
We're open from {openHour}:00 until {closeHour}:00.
Come visit us or order online.
</p>
<button className="btn">Order</button>
</div>
);
}注意事项
- 务必使用花括号:解构赋值必须使用
{}花括号,这是初学者常见的错误 - 属性名必须匹配:解构的属性名必须与传入的props名称完全一致
- 解构不存在的属性:如果解构一个不存在的属性,结果将是
undefined
实践建议
在实际开发中,我推荐始终使用解构来接收组件props。这样可以让你的代码更加清晰,同时也更容易理解每个组件需要什么样的数据。
在处理复杂组件时,解构还能让你一目了然地看到组件的”接口”——它需要哪些数据才能正常工作。
完整代码(点击展开)
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
const pizzaData = [
{
name: "Focaccia",
ingredients: "Bread with italian olive oil and rosemary",
price: 6,
photoName: "pizzas/focaccia.jpg",
soldOut: false,
},
{
name: "Pizza Margherita",
ingredients: "Tomato and mozarella",
price: 10,
photoName: "pizzas/margherita.jpg",
soldOut: false,
},
{
name: "Pizza Spinaci",
ingredients: "Tomato, mozarella, spinach, and ricotta cheese",
price: 12,
photoName: "pizzas/spinaci.jpg",
soldOut: false,
},
{
name: "Pizza Funghi",
ingredients: "Tomato, mozarella, mushrooms, and onion",
price: 12,
photoName: "pizzas/funghi.jpg",
soldOut: false,
},
{
name: "Pizza Salamino",
ingredients: "Tomato, mozarella, and pepperoni",
price: 15,
photoName: "pizzas/salamino.jpg",
soldOut: true,
},
{
name: "Pizza Prosciutto",
ingredients: "Tomato, mozarella, ham, aragula, and burrata cheese",
price: 18,
photoName: "pizzas/prosciutto.jpg",
soldOut: false,
},
];
function App() {
return (
<div className="container">
<Header />
<Menu />
<Footer />
</div>
);
}
function Header() {
const style = {};
return (
<header className="header">
<h1 style={style}>Fast React Pizza Co.</h1>
</header>
);
}
function Menu() {
const pizzas = pizzaData;
// const pizzas = [];
const numPizzas = pizzas.length;
return (
<main className="menu">
<h2>Our Menu</h2>
{numPizzas > 0 ? (
<>
<p>我们提供多种美味的比萨选择,全部使用新鲜原料制作。</p>
<ul className="pizzas">
{pizzas.map((pizza) => (
<Pizza pizzaObj={pizza} key={pizza.name} />
))}
</ul>
</>
) : (
<p>We're still working on our menu. Please come back later</p>
)}
{/* <Pizza
name="Pizza Spinaci"
ingredient="Tomato, mozarella, spinach, and ricotta cheese"
photoName="pizzas/spinaci.jpg"
price={10}
/>
<Pizza
name="Pizza Funghi"
ingredient="Tomato, mushrooms"
price={12}
photoName="pizzas/funghi.jpg"
/> */}
</main>
);
}
function Pizza({ pizzaObj }) {
if (pizzaObj.soldOut) {
return null;
}
return (
<li className="pizza">
<img src={pizzaObj.photoName} alt={pizzaObj.name}></img>
<div>
<h3>{pizzaObj.name}</h3>
<p>{pizzaObj.ingredients}</p>
<span>{pizzaObj.price}</span>
</div>
</li>
);
}
function Footer() {
const hour = new Date().getHours();
const openHour = 20;
const closeHour = 22;
const isOpen = hour >= openHour && hour <= closeHour;
console.log(isOpen);
return (
<footer className="footer">
{isOpen ? (
<Order closeHour={closeHour} openHour={openHour} />
) : (
<p>
We're happy to welcome you between {openHour}:00 and {closeHour}:00
</p>
)}
</footer>
);
}
function Order({ closeHour, openHour }) {
return (
<div className="order">
<p>
We're open from {openHour}:00 to {closeHour}:00. Come visit us or order
online.
</p>
<button className="btn">Order</button>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

发表回复