如何將 true 值傳遞給給定的 props?【相關推薦:Redis視訊教學、】
在下面的範例中,使用 prop showTitle
在導航欄元件中顯示應用的標題:
export default function App() {
return (
<main>
<Navbar showTitle={true} />
</main>
);
}
function Navbar({ showTitle }) {
return (
<div>
{showTitle && <h1>標題</h1>}
</div>
)
}
登入後複製
這裡將 showTitle
顯式設定為布林值 true
,其實這是沒必要的,因為元件上提供的任何 prop
都具有預設值 true
。因此只需要在呼叫元件時傳遞一個 showTitle
即可:
export default function App() {
return (
<main>
<Navbar showTitle />
</main>
);
}
function Navbar({ showTitle }) {
return (
<div>
{showTitle && <h1>標題</h1>}
</div>
)
}
登入後複製
另外,當需要傳遞一個字串作為 props
時,無需使用花括號 {}
包裹,可以通過雙引號包裹字串內容並傳遞即可:
export default function App() {
return (
<main>
<Navbar title="標題" />
</main>
);
}
function Navbar({ title }) {
return (
<div>
<h1>{title}</h1>
</div>
)
}
登入後複製
編寫更簡潔的 React 程式碼的最簡單和最重要的方法就是善於將程式碼抽象為單獨的 React 元件。
下面來看一個例子,應用中最上面會有一個導航欄,並遍歷 posts
中的資料將文章標題渲染出來:
export default function App() {
const posts = [
{
id: 1,
title: "標題1"
},
{
id: 2,
title: "標題2"
}
];
return (
<main>
<Navbar title="大標題" />
<ul>
{posts.map(post => (
<li key={post.id}>
{post.title}
</li>
))}
</ul>
</main>
);
}
function Navbar({ title }) {
return (
<div>
<h1>{title}</h1>
</div>
);
}
登入後複製
那我們怎樣才能讓這段程式碼更加清潔呢?我們可以抽象迴圈中的程式碼(文章標題),將它們抽離到一個單獨的元件中,稱之為 FeaturedPosts
。抽離後的程式碼如下:
export default function App() {
return (
<main>
<Navbar title="大標題" />
<FeaturedPosts />
</main>
);
}
function Navbar({ title }) {
return (
<div>
<h1>{title}</h1>
</div>
);
}
function FeaturedPosts() {
const posts = [
{
id: 1,
title: "標題1"
},
{
id: 2,
title: "標題2"
}
];
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
如你所見,在 App 元件中,通過其中的元件名稱:Navbar
和 FeaturedPosts
,就可以快速地看到應用的作用。
在上面的例子中,我們將三個元件在一個檔案中實現。如果元件邏輯較少,這些寫還沒啥問題,但是如果元件邏輯較為複雜,那這樣寫程式碼的可讀性就很差了。為了使應用檔案更具可讀性,可以將每個元件放入一個單獨的檔案中。
這可以幫助我們在應用中分離關注點。 這意味著每個檔案只負責一個元件,如果想在應用中重用它,就不會混淆元件的來源:
// src/App.js
import Navbar from './components/Navbar.js';
import FeaturedPosts from './components/FeaturedPosts.js';
export default function App() {
return (
<main>
<Navbar title="大標題" />
<FeaturedPosts />
</main>
);
}
登入後複製
// src/components/Navbar.js
export default function Navbar({ title }) {
return (
<div>
<h1>{title}</h1>
</div>
);
}
登入後複製
// src/components/FeaturedPosts.js
export default function FeaturedPosts() {
const posts = [
{
id: 1,
title: "標題1"
},
{
id: 2,
title: "標題2"
}
];
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
此外,通過將每個單獨的元件包含在其自己的檔案中,可以避免一個檔案變得過於臃腫。
在 FeaturedPosts 元件,假設想要從 API 獲取文章資料,而不是使用假資料。可以使用 fetch API 來實現:
import React from 'react';
export default function FeaturedPosts() {
const [posts, setPosts] = React.useState([]);
React.useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => setPosts(data));
}, []);
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
但是,如果想在多個元件執行這個資料請求怎麼辦?
假設除了 FeaturedPosts 元件之外,還又一個名為 Posts 的元件,其中包含相同的資料。 我們必須複製用於獲取資料的邏輯並將其貼上到該元件中。為了避免重複編寫程式碼,可以定義一個新的 React hook,可以稱之為 useFetchPosts:
import React from 'react';
export default function useFetchPosts() {
const [posts, setPosts] = React.useState([]);
React.useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then(res => res.json())
.then(data => setPosts(data));
}, []);
return posts;
}
登入後複製
這樣就可以在任何元件中重用它,包括 FeaturedPosts 元件:
import useFetchPosts from '../hooks/useFetchPosts.js';
export default function FeaturedPosts() {
const posts = useFetchPosts()
return (
<ul>
{posts.map((post) => (
<li key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
另一種簡化元件的方式就是從 JSX 中刪除儘可能多的 JavaScript。來看下面的例子:
import useFetchPosts from '../hooks/useFetchPosts.js';
export default function FeaturedPosts() {
const posts = useFetchPosts()
return (
<ul>
{posts.map((post) => (
<li onClick={event => {
console.log(event.target, 'clicked!');
}} key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
這裡我們嘗試處理文章的點選事件,可以看到我們的 JSX 變得更加難以閱讀。 鑑於函數是作為行內函式包含的,它掩蓋了這個元件的用途,以及它的相關函數。
那該如何來解決這個問題?可以將包含 onClick 的行內函式提取到一個單獨的處理常式中,給它一個名稱 handlePostClick。這樣 JSX 的可讀性就變高了:
import useFetchPosts from '../hooks/useFetchPosts.js';
export default function FeaturedPosts() {
const posts = useFetchPosts()
function handlePostClick(event) {
console.log(event.target, 'clicked!');
}
return (
<ul>
{posts.map((post) => (
<li onClick={handlePostClick} key={post.id}>{post.title}</li>
))}
</ul>
);
}
登入後複製
在 JSX 中編寫過多的內聯樣式就會讓程式碼更難閱讀並且變得臃腫:
export default function App() {
return (
<main style={{ textAlign: 'center' }}>
<Navbar title="大標題" />
</main>
);
}
function Navbar({ title }) {
return (
<div style={{ marginTop: '20px' }}>
<h1 style={{ fontWeight: 'bold' }}>{title}</h1>
</div>
)
}
登入後複製
我們要儘可能地將內聯樣式移動到 CSS 樣式表中。或者將它們組織成物件:
export default function App() {
const styles = {
main: { textAlign: "center" }
};
return (
<main style={styles.main}>
<Navbar title="大標題" />
</main>
);
}
function Navbar({ title }) {
const styles = {
div: { marginTop: "20px" },
h1: { fontWeight: "bold" }
};
return (
<div style={styles.div}>
<h1 style={styles.h1}>{title}</h1>
</div>
);
}
登入後複製
一般情況下,最好將這些樣式寫在CSS樣式表中,如果樣式需要動態生成,可以將其定義在一個物件中。
在 JavaScript 中,我們需要首先確保物件存在,然後才能存取它的屬性。如果物件的值為undefined 或者 null,則會導致型別錯誤。
下面來看一個例子,使用者可以在其中編輯他們釋出的貼文。只有當isPostAuthor 為 true 時,也就是經過身份驗證的使用者的 id 與貼文作者的 id 相同時,才會顯示該EditButton元件。
export default function EditButton({ post }) {
const user = useAuthUser();
const isPostAuthor = post.author.userId !== user && user.userId;
return isPostAuthor ? <EditButton /> : null;
}
登入後複製
這段程式碼的問題是 user 可能是 undefined. 這就是為什麼我們必須在嘗試獲取 userId 屬性之前使用 && 運運算元來確保 user 是一個物件。如果我要存取一個物件中的另一個物件,就不得不再包含一個 && 條件。 這會導致程式碼變得複雜、難以理解。
JavaScript 可選鏈運運算元(?.)允許我們在存取屬性之前檢查物件是否存在。用它來簡化上面的程式碼:
export default function EditButton({ post }) {
const user = useAuthUser();
const isPostAuthor = post.author.userId !== user?.userId;
return isPostAuthor ? <EditButton /> : null;
}
登入後複製
這樣將防止任何型別錯誤,並允許我們編寫更清晰的條件邏輯。
在 React 應用中可以使用 function 關鍵字的函數宣告語法編寫元件,也可以使用設定為變數的箭頭函數。使用 function 關鍵字的元件必須在返回任何 JSX 之前使用 return 關鍵字。
export default function App() {
return (
<Layout>
<Routes />
</Layout>
);
}
登入後複製
通過將返回的程式碼包裹在一組括號中,可以通過隱式返回(不使用 return 關鍵字)從函數返回多行 JavaScript 程式碼。
對於使用箭頭函數的元件,不需要包含 return 關鍵字,可以只返回帶有一組括號的 JSX。
const App = () => (
<Layout>
<Routes />
</Layout>
);
export default App;
登入後複製
此外,當使用 .map()
迭代元素列表時,還可以跳過 return
關鍵字並僅在內部函數的主體中使用一組括號返回 JSX。
function PostList() {
const posts = usePostData();
return posts.map(post => (
<PostListItem key={post.id} post={post} />
))
}
登入後複製
在 JavaScript 中,如果某個值是假值(如 null、undefined、0、''、NaN),可以使用 || 條件來提供一個備用值。
例如,在產品頁面元件需要顯示給定產品的價格,可以使用 || 來有條件地顯示價格或顯示文字「產品不可用」。
export default function ProductPage({ product }) {
return (
<>
<ProductDetails />
<span>
{product.price || "產品不可用"}
</span>
</>
);
}
登入後複製
現有的程式碼存在一個問題,如果商品的價格為0,也不會顯示產品的價格而顯示"產品不可用"。如果左側為null
或者undefined
,而不是其他假值,就需要一個更精確的運運算元來僅返回表示式的右側。
這時就可以使用空值合併運運算元,當左側運算元為null或者 undefined 時,將返回右側運算元。 否則它將返回其左側運算元:
null ?? 'callback';
// "callback"
0 ?? 42;
// 0
登入後複製
可以使用空值合併運運算元來修復上面程式碼中的問題:
export default function ProductPage({ product }) {
return (
<>
<ProductDetails />
<span>{product.price ?? "產品不可用"}
</>
);
}
登入後複製
在 React 元件中編寫條件時,三元表示式是必不可少的,經常用於顯示或隱藏元件和元素。
當然,我們用可以使用三元表示式和模板字串來給 React 元素動態新增或刪除類名。
export default function App() {
const { isDarkMode } = useDarkMode();
return (
<main className={`body ${isDarkMode ? "body-dark" : "body-light"}`}>
<Routes />
</main>
);
}
登入後複製
這種條件邏輯也可以應用於任何 props:
export default function App() {
const { isMobile } = useDeviceDetect();
return (
<Layout height={isMobile ? '100vh' : '80vh'}>
<Routes />
</Layout>
);
}
登入後複製
【推薦學習:】
以上就是10 個編寫更簡潔React程式碼的實用小技巧的詳細內容,更多請關注TW511.COM其它相關文章!