掌握React條件渲染的方法

掌握React條件渲染的方法

條件渲染是React的一個強大功能,它允許開發者根據某些條件渲染元件。

它是一個基本概念,在構建動態和互動式網路應用程式中起著關鍵作用。

在這個全面的指南中,我們將深入研究React中的條件渲染,涵蓋基本和高階技術,並通過例項來正確理解。

  1. 瞭解React中的條件渲染
  2. 條件渲染的基本技術
  3. 條件渲染的高階技術

瞭解React中的條件渲染

React中的條件渲染允許開發者根據特定的值動態地控制螢幕上顯示的內容,這些值可以儲存在變數、狀態或道具中。

這在你想顯示或隱藏某些UI元素,改變頁面佈局,或根據使用者互動渲染不同內容的情況下是非常有用的。

條件渲染在React應用程式中很重要,因為它使你能夠建立動態和互動的使用者介面,能夠實時響應不斷變化的資料和使用者互動。

它將有助於提高你的應用程式的效能和效率,避免不必要地渲染不需要的元件或元素。

條件渲染的基本技術

在React中,有幾種基本技術可以用來進行條件渲染。讓我們來詳細探討一下每一種技術。

使用if語句進行條件渲染

在React中實現條件渲染的最直接的方法之一是使用傳統的 if 語句。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
if (condition) {
return <p>Expression 1</p>;
} else {
return <p>Expression 2</p>;
}
if (condition) { return <p>Expression 1</p>; } else { return <p>Expression 2</p>; }
if (condition) {
return <p>Expression 1</p>;
} else {
return <p>Expression 2</p>;
}

JavaScript的 if 語句可以在你的元件的 render() 方法中使用,根據某個條件有條件地渲染內容。

例如,你可以使用if語句,在等待資料載入時顯示一個載入旋鈕:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
// Fetch data from an API
fetch('https://example.com/data')
.then((response) => response.json())
.then((data) => {
setData(data);
setIsLoading(false);
});
}, []);
if (isLoading) {
return <Spinner />;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;
import { useState, useEffect } from 'react'; import Spinner from './Spinner'; const MyComponent = () => { const [isLoading, setIsLoading] = useState(true); const [data, setData] = useState(null); useEffect(() => { // Fetch data from an API fetch('https://example.com/data') .then((response) => response.json()) .then((data) => { setData(data); setIsLoading(false); }); }, []); if (isLoading) { return <Spinner />; } return <div>{/* Render the data here */}</div>; }; export default MyComponent;
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
// Fetch data from an API
fetch('https://example.com/data')
.then((response) => response.json())
.then((data) => {
setData(data);
setIsLoading(false);
});
}, []);
if (isLoading) {
return <Spinner />;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;

在這個例子中, MyComponent 使用 useEffect 鉤子從一個API獲取資料。在等待資料載入時,我們使用 if 語句顯示一個Spinner元件。

另一個例子是,當渲染你的元件時發生錯誤,可以渲染一個後備UI:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const MyComponent = ({ data }) => {
if (!data) {
return <p>Something went wrong. Please try again later.</p>;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;
const MyComponent = ({ data }) => { if (!data) { return <p>Something went wrong. Please try again later.</p>; } return <div>{/* Render the data here */}</div>; }; export default MyComponent;
const MyComponent = ({ data }) => {
if (!data) {
return <p>Something went wrong. Please try again later.</p>;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;

在這段程式碼中,我們有一個 MyComponent ,它需要一個 data 道具。如果 data 道具是錯誤的,我們使用 if 語句渲染一個錯誤資訊。

最後,你可以用 if 語句為不同的使用者角色顯示不同的內容:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const MyComponent = ({ user }) => {
if (user.role === 'admin') {
return <p>Welcome, admin!</p>;
} else if (user.role === 'user') {
return <p>Welcome, user!</p>;
} else {
return <p>You are not authorized to access this page.</p>;
}
};
export default MyComponent;
const MyComponent = ({ user }) => { if (user.role === 'admin') { return <p>Welcome, admin!</p>; } else if (user.role === 'user') { return <p>Welcome, user!</p>; } else { return <p>You are not authorized to access this page.</p>; } }; export default MyComponent;
const MyComponent = ({ user }) => {
if (user.role === 'admin') {
return <p>Welcome, admin!</p>;
} else if (user.role === 'user') {
return <p>Welcome, user!</p>;
} else {
return <p>You are not authorized to access this page.</p>;
}
};
export default MyComponent;

在這段程式碼中,我們有一個 MyComponent ,它接受一個 user 道具。根據 user.role 屬性,我們使用 if 語句顯示不同的內容。

使用三元運算子進行條件性渲染

在React中實現條件渲染的另一個簡潔的方法是在JJSX中使用三元運算子 (?)。

三元運算子允許你通過指定3個運算數來寫一個緊湊的內聯if-else語句。第一個運算元是條件,而其他兩個運算元是表示式。如果條件為 true,第一個表示式將被執行;否則,第二個表示式。

例如,你可以根據一個道具渲染不同的元件:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const ExampleComponent = ({ shouldRenderComponentA }) => {
return (
<div>
{shouldRenderComponentA ? <ComponentA /> : <ComponentB />}
</div>
);
};
export default ExampleComponent;
import ComponentA from './ComponentA'; import ComponentB from './ComponentB'; const ExampleComponent = ({ shouldRenderComponentA }) => { return ( <div> {shouldRenderComponentA ? <ComponentA /> : <ComponentB />} </div> ); }; export default ExampleComponent;
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const ExampleComponent = ({ shouldRenderComponentA }) => {
return (
<div>
{shouldRenderComponentA ? <ComponentA /> : <ComponentB />}
</div>
);
};
export default ExampleComponent;

在這段程式碼中,我們有一個名為 shouldRenderComponentA 的道具的 ExampleComponent 。我們使用三元運算子,根據道具值有條件地渲染 ComponentAComponentB

你也可以根據一個狀態渲染不同的文字:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState } from 'react';
const ExampleComponent = () => {
const [showMessage, setShowMessage] = useState(false);
return (
<div>
<button onClick={() => setShowMessage(!showMessage)}>
{showMessage ? 'Hide message' : 'Show message'}
</button>
{showMessage ? <p>Hello, world!</p> : null}
</div>
);
};
export default ExampleComponent;
import { useState } from 'react'; const ExampleComponent = () => { const [showMessage, setShowMessage] = useState(false); return ( <div> <button onClick={() => setShowMessage(!showMessage)}> {showMessage ? 'Hide message' : 'Show message'} </button> {showMessage ? <p>Hello, world!</p> : null} </div> ); }; export default ExampleComponent;
import { useState } from 'react';
const ExampleComponent = () => {
const [showMessage, setShowMessage] = useState(false);
return (
<div>
<button onClick={() => setShowMessage(!showMessage)}>
{showMessage ? 'Hide message' : 'Show message'}
</button>
{showMessage ? <p>Hello, world!</p> : null}
</div>
);
};
export default ExampleComponent;

在這個例子中,我們使用三元運算子,根據 showMessage 狀態的值,有條件地呈現不同的文字。當按鈕被點選時, showMessage 的值被切換,文字也相應地被顯示或隱藏。

最後,你可以在獲取資料時渲染一個載入旋鈕:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const ExampleComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const jsonData = await response.json();
setData(jsonData);
setIsLoading(false);
};
fetchData();
}, []);
return (
<div>
{isLoading ? <Spinner /> : <p>{data.title}</p>}
</div>
);
};
export default ExampleComponent;
import { useState, useEffect } from 'react'; import Spinner from './Spinner'; const ExampleComponent = () => { const [isLoading, setIsLoading] = useState(true); const [data, setData] = useState(null); useEffect(() => { const fetchData = async () => { const response = await fetch('https://jsonplaceholder.typicode.com/todos/1'); const jsonData = await response.json(); setData(jsonData); setIsLoading(false); }; fetchData(); }, []); return ( <div> {isLoading ? <Spinner /> : <p>{data.title}</p>} </div> ); }; export default ExampleComponent;
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const ExampleComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const jsonData = await response.json();
setData(jsonData);
setIsLoading(false);
};
fetchData();
}, []);
return (
<div>
{isLoading ? <Spinner /> : <p>{data.title}</p>}
</div>
);
};
export default ExampleComponent;

在這個例子中,我們使用三元運算子,在從API獲取資料時,有條件地渲染一個載入旋鈕。一旦資料可用,我們就使用三元運算子渲染 title 屬性。

使用邏輯 AND 和 OR 操作符進行條件渲染

你也可以使用邏輯AND(&&)和 OR(||)運算子來實現React中的條件渲染。

邏輯AND操作符允許你只在某個條件為真時渲染一個元件,而邏輯OR操作符允許你在任一條件為真時渲染一個元件。

當你有簡單的條件來決定一個元件是否應該被渲染時,這些運算子很有用。例如,如果你想只在表單有效的情況下渲染一個按鈕,你可以像這樣使用邏輯和運算子:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState } from 'react';
const FormComponent = () => {
const [formValues, setFormValues] = useState({ username: "", password: "" });
const isFormValid = formValues.username && formValues.password;
const handleSubmit = (event) => {
event.preventDefault();
// Submit form data
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={formValues.username}
placeholder="Type Username..."
onChange={(e) =>
setFormValues({ ...formValues, username: e.target.value })
}
/>
<br />
<input
type="password"
value={formValues.password}
placeholder="Type Password..."
onChange={(e) =>
setFormValues({ ...formValues, password: e.target.value })
}
/>
{isFormValid && <button type="submit">Submit</button>}
</form>
);
};
export default FormComponent;
import { useState } from 'react'; const FormComponent = () => { const [formValues, setFormValues] = useState({ username: "", password: "" }); const isFormValid = formValues.username && formValues.password; const handleSubmit = (event) => { event.preventDefault(); // Submit form data }; return ( <form onSubmit={handleSubmit}> <input type="text" value={formValues.username} placeholder="Type Username..." onChange={(e) => setFormValues({ ...formValues, username: e.target.value }) } /> <br /> <input type="password" value={formValues.password} placeholder="Type Password..." onChange={(e) => setFormValues({ ...formValues, password: e.target.value }) } /> {isFormValid && <button type="submit">Submit</button>} </form> ); }; export default FormComponent;
import { useState } from 'react';
const FormComponent = () => {
const [formValues, setFormValues] = useState({ username: "", password: "" });
const isFormValid = formValues.username && formValues.password;
const handleSubmit = (event) => {
event.preventDefault();
// Submit form data
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={formValues.username}
placeholder="Type Username..."
onChange={(e) =>
setFormValues({ ...formValues, username: e.target.value })
}
/>
<br />
<input
type="password"
value={formValues.password}
placeholder="Type Password..."
onChange={(e) =>
setFormValues({ ...formValues, password: e.target.value })
}
/>
{isFormValid && <button type="submit">Submit</button>}
</form>
);
};
export default FormComponent;

在這個例子中,我們有一個 FormComponent ,它有一個帶有 username 和 password 兩個輸入域的表單。我們使用 useState 鉤子來管理表單的值,使用 isFormValid 變數來檢查兩個輸入欄位是否有值。使用邏輯和運算子(&&),我們只有在 isFormValid 為真時才渲染提交按鈕。這就保證了只有在表單有效的情況下才會啟用按鈕。

類似地,你可以使用OR運算子,在資料仍在載入的情況下呈現一個載入資訊,或者在發生錯誤時呈現一個錯誤資訊:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React, { useEffect, useState } from 'react';
const DataComponent = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
} catch (error) {
setErrorMessage('An error occurred while fetching data.');
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
return (
<>
{errorMessage || isLoading ? (
<p>{errorMessage || 'Loading...'}</p>
) : (
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</>
);
};
export default DataComponent;
import React, { useEffect, useState } from 'react'; const DataComponent = () => { const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(true); const [errorMessage, setErrorMessage] = useState(''); useEffect(() => { const fetchData = async () => { try { const response = await fetch('https://api.example.com/data'); const data = await response.json(); setData(data); } catch (error) { setErrorMessage('An error occurred while fetching data.'); } finally { setIsLoading(false); } }; fetchData(); }, []); return ( <> {errorMessage || isLoading ? ( <p>{errorMessage || 'Loading...'}</p> ) : ( <ul> {data.map((item) => ( <li key={item.id}>{item.name}</li> ))} </ul> )} </> ); }; export default DataComponent;
import React, { useEffect, useState } from 'react';
const DataComponent = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
} catch (error) {
setErrorMessage('An error occurred while fetching data.');
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
return (
<>
{errorMessage || isLoading ? (
<p>{errorMessage || 'Loading...'}</p>
) : (
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</>
);
};
export default DataComponent;

在這個例子中,一個 DataComponent 使用fetch從API中獲取資料,並將其顯示在一個列表中。我們使用 useState 鉤子來管理資料、載入狀態和錯誤資訊。使用邏輯OR操作符(||),如果其中一個條件為真,我們可以呈現一個載入資訊或一個錯誤資訊。這確保了使用者看到的資訊表明了資料獲取過程的當前狀態。

在React中使用邏輯AND和OR運算子進行條件渲染是處理簡單條件的一種簡潔和可讀的方式。然而,對於更復雜的邏輯,最好使用其他方法,如 switch 語句。

條件渲染的高階技術

React中的條件渲染可以更加複雜,這取決於你的應用程式的要求。這裡有一些高階技術,你可以在更復雜的情況下使用條件渲染。

使用Switch語句進行條件渲染

雖然if語句和三元運算子是條件渲染的常見方法,但有時 switch 語句可能更合適,特別是在處理多個條件時。

下面是一個例子:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import React from 'react';
const MyComponent = ({ userType }) => {
switch (userType) {
case 'admin':
return <p>Welcome, admin user!</p>;
case 'user':
return <p>Welcome, regular user!</p>;
default:
return <p>Please log in to continue.</p>;
}
};
export default MyComponent;
import React from 'react'; const MyComponent = ({ userType }) => { switch (userType) { case 'admin': return <p>Welcome, admin user!</p>; case 'user': return <p>Welcome, regular user!</p>; default: return <p>Please log in to continue.</p>; } }; export default MyComponent;
import React from 'react';
const MyComponent = ({ userType }) => {
switch (userType) {
case 'admin':
return <p>Welcome, admin user!</p>;
case 'user':
return <p>Welcome, regular user!</p>;
default:
return <p>Please log in to continue.</p>;
}
};
export default MyComponent;

在這段程式碼中,一個 switch 語句被用來根據 userType 道具有條件地渲染內容。這種方法在處理多個條件時很有幫助,併為處理複雜的邏輯提供了一種更有組織和可讀的方式。

使用React Router的條件渲染

React Router是一個流行的庫,用於處理React應用程式中的客戶端路由。React Router允許你根據當前路由有條件地渲染元件。

下面是一個使用React Router實現條件渲染的例子:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import { useState } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';
import NotFound from './components/NotFound';
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login">
<Login setIsLoggedIn={setIsLoggedIn} />
</Route>
{isLoggedIn ? (
<Route path="/dashboard" component={Dashboard} />
) : (
<Route component={NotFound} />
)}
</Switch>
</Router>
);
};
export default App;
import { useState } from 'react'; import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Home from './components/Home'; import Login from './components/Login'; import Dashboard from './components/Dashboard'; import NotFound from './components/NotFound'; const App = () => { const [isLoggedIn, setIsLoggedIn] = useState(false); return ( <Router> <Switch> <Route exact path="/" component={Home} /> <Route path="/login"> <Login setIsLoggedIn={setIsLoggedIn} /> </Route> {isLoggedIn ? ( <Route path="/dashboard" component={Dashboard} /> ) : ( <Route component={NotFound} /> )} </Switch> </Router> ); }; export default App;
import { useState } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';
import NotFound from './components/NotFound';
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login">
<Login setIsLoggedIn={setIsLoggedIn} />
</Route>
{isLoggedIn ? (
<Route path="/dashboard" component={Dashboard} />
) : (
<Route component={NotFound} />
)}
</Switch>
</Router>
);
};
export default App;

在這段程式碼中,我們使用 isLoggedIn 狀態,如果使用者已經登入,就有條件地渲染 Dashboard 元件,如果使用者沒有登入,就渲染 NotFound 元件。一旦使用者成功登入, Login 元件就會將 isLoggedIn 狀態設定為 true

注意,我們正在使用 <Route> 元件的子節點道具來傳遞 Login 元件和 setIsLoggedIn 函式。這允許我們向 Login 元件傳遞道具,而不需要在 path 道具中指定它。

小結

條件渲染是React中一項強大的技術,它允許你根據不同的條件動態地更新UI。

根據你的應用程式的UI邏輯的複雜性,你可以選擇最適合你需要的方法。

記住要保持你的程式碼乾淨、有條理和可讀性,並始終徹底測試你的條件渲染邏輯,以確保它在不同場景下都能按預期工作。

評論留言