前言
generatePath
是 React Router
的一個實用工具函數,用于根據路徑模式和參數對象生成實際的 URL 路徑。它在需要動態構建鏈接的場景中非常有用,比如生成導航鏈接或重定向路徑。
1、基本用法和注意事項
import { generatePath } from 'react-router-dom';// 基本用法
const path = generatePath('/users/:id', // 路徑模式{ id: 123 } // 參數對象
);console.log(path); // 輸出: '/users/123'
2、注意事項
- 參數順序:第一個參數是路徑模式,第二個是參數對象
- 必需參數:路徑模式中所有非可選參數必須在參數對象中提供
- 可選參數:使用 :paramName? 語法表示可選參數
- 額外參數:參數對象中的額外屬性會被忽略(不會轉換為查詢參數)
- 編碼處理:參數值會自動進行 URL 編碼
3、實際案例演示
下面是一個演示頁面,展示 generatePath
的各種用法:
// 注意:這是一個演示用的React組件,需要在React環境中運行
import React, { useState } from 'react';const GeneratePathDemo = () => {// 模擬 generatePath 函數const generatePath = (pattern, params) => {return pattern.replace(/:(\w+)(\?)?/g, (match, paramName, optional) => {// 檢查參數是否存在if (params[paramName] === undefined && !optional) {return `:${paramName}(missing)`;}return params[paramName] !== undefined ? encodeURIComponent(params[paramName]) : '';});};const [pattern, setPattern] = useState('/users/:id/posts/:postId');const [params, setParams] = useState({id: '123',postId: '456'});const [paramKey, setParamKey] = useState('');const [paramValue, setParamValue] = useState('');const addParam = () => {if (paramKey && paramValue !== '') {setParams(prev => ({ ...prev, [paramKey]: paramValue }));setParamKey('');setParamValue('');}};const removeParam = (key) => {setParams(prev => {const newParams = { ...prev };delete newParams[key];return newParams;});};const generatedPath = generatePath(pattern, params);return (<div style={{ padding: '20px', maxWidth: '800px', margin: '0 auto', fontFamily: 'Arial, sans-serif' }}><h1 style={{ color: '#333', borderBottom: '2px solid #007acc', paddingBottom: '10px' }}>React Router generatePath 實用函數演示</h1><div style={{ marginBottom: '20px', padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '5px' }}><h3 style={{ color: '#007acc' }}>路徑模式</h3><input type="text" value={pattern} onChange={e => setPattern(e.target.value)}style={{ width: '100%', padding: '8px', fontSize: '16px' }}placeholder="輸入路徑模式,如 /users/:id"/><p style={{ fontSize: '14px', color: '#666', marginTop: '5px' }}>使用 <code>:paramName</code> 表示必需參數,<code>:paramName?</code> 表示可選參數</p></div><div style={{ marginBottom: '20px', padding: '15px', backgroundColor: '#e8f4f8', borderRadius: '5px' }}><h3 style={{ color: '#007acc' }}>參數設置</h3><div style={{ display: 'flex', gap: '10px', marginBottom: '10px' }}><inputtype="text"value={paramKey}onChange={e => setParamKey(e.target.value)}placeholder="參數名"style={{ padding: '8px', flex: 1 }}/><inputtype="text"value={paramValue}onChange={e => setParamValue(e.target.value)}placeholder="參數值"style={{ padding: '8px', flex: 1 }}/><button onClick={addParam}style={{ padding: '8px 15px', backgroundColor: '#007acc', color: 'white', border: 'none', borderRadius: '4px' }}>添加參數</button></div><div><h4>當前參數:</h4>{Object.keys(params).length === 0 ? (<p>暫無參數</p>) : (<ul style={{ listStyle: 'none', padding: 0 }}>{Object.entries(params).map(([key, value]) => (<li key={key} style={{ padding: '5px', backgroundColor: 'white', marginBottom: '5px', borderRadius: '3px', display: 'flex', justifyContent: 'space-between' }}><span><strong>{key}:</strong> {value}</span><button onClick={() => removeParam(key)}style={{ backgroundColor: '#ff4757', color: 'white', border: 'none', borderRadius: '3px', padding: '2px 8px' }}>刪除</button></li>))}</ul>)}</div></div><div style={{ marginBottom: '20px', padding: '15px', backgroundColor: '#f0f0f0', borderRadius: '5px' }}><h3 style={{ color: '#007acc' }}>生成結果</h3><div style={{ padding: '15px', backgroundColor: 'white', borderRadius: '5px', fontSize: '18px', fontWeight: 'bold' }}>{generatedPath}</div></div><div style={{ padding: '15px', backgroundColor: '#f5f5f5', borderRadius: '5px' }}><h3 style={{ color: '#007acc' }}>常見用例示例</h3><div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '10px' }}><div style={{ padding: '10px', backgroundColor: 'white', borderRadius: '5px' }}><h4>用戶資料頁</h4><p>模式: <code>/users/:userId</code></p><p>參數: <code>{`{userId: "abc123"}`}</code></p><p>結果: <code>/users/abc123</code></p><button onClick={() => {setPattern('/users/:userId');setParams({ userId: 'abc123' });}}style={{ padding: '5px 10px', backgroundColor: '#007acc', color: 'white', border: 'none', borderRadius: '3px' }}>嘗試此示例</button></div><div style={{ padding: '10px', backgroundColor: 'white', borderRadius: '5px' }}><h4>博客文章</h4><p>模式: <code>/blog/:year/:month/:slug</code></p><p>參數: <code>{`{year: "2023", month: "09", slug: "react-tutorial"}`}</code></p><p>結果: <code>/blog/2023/09/react-tutorial</code></p><button onClick={() => {setPattern('/blog/:year/:month/:slug');setParams({ year: '2023', month: '09', slug: 'react-tutorial' });}}style={{ padding: '5px 10px', backgroundColor: '#007acc', color: 'white', border: 'none', borderRadius: '3px' }}>嘗試此示例</button></div><div style={{ padding: '10px', backgroundColor: 'white', borderRadius: '5px' }}><h4>可選參數</h4><p>模式: <code>/products/:category?/:id</code></p><p>參數: <code>{`{id: "12345"}`}</code></p><p>結果: <code>/products/12345</code></p><button onClick={() => {setPattern('/products/:category?/:id');setParams({ id: '12345' });}}style={{ padding: '5px 10px', backgroundColor: '#007acc', color: 'white', border: 'none', borderRadius: '3px' }}>嘗試此示例</button></div><div style={{ padding: '10px', backgroundColor: 'white', borderRadius: '5px' }}><h4>多參數</h4><p>模式: <code>/search/:type/:query/sort/:sortBy</code></p><p>參數: <code>{`{type: "users", query: "john", sortBy: "date"}`}</code></p><p>結果: <code>/search/users/john/sort/date</code></p><button onClick={() => {setPattern('/search/:type/:query/sort/:sortBy');setParams({ type: 'users', query: 'john', sortBy: 'date' });}}style={{ padding: '5px 10px', backgroundColor: '#007acc', color: 'white', border: 'none', borderRadius: '3px' }}>嘗試此示例</button></div></div></div><div style={{ marginTop: '20px', padding: '15px', backgroundColor: '#e8f4f8', borderRadius: '5px' }}><h3 style={{ color: '#007acc' }}>注意事項</h3><ul style={{ lineHeight: '1.6' }}><li>確保為所有必需參數提供值,否則生成的路徑會包含 <code>:paramName(missing)</code></li><li>可選參數使用 <code>:paramName?</code> 語法</li><li>參數值會自動進行 URL 編碼</li><li>參數對象中的額外屬性會被忽略(不會轉換為查詢參數)</li><li>在實際應用中,應從 <code>react-router-dom</code> 導入 <code>generatePath</code></li></ul></div></div>);
};export default GeneratePathDemo;
3.1、關鍵用例說明
- 動態導航:生成帶參數的鏈接用于導航
- 重定向路徑:在程序化導航中構建目標路徑
- 數據獲取:構建API端點URL
- 分享鏈接:生成包含特定參數的URL用于分享
4、注意事項總結
- 確保為所有必需參數提供值,否則會得到包含未替換參數的路徑
- 使用可選參數語法(:paramName?)來處理可能不存在的參數
- 參數值會自動進行URL編碼,無需手動處理特殊字符
- 參數對象中的額外屬性不會被處理為查詢參數
- 在實際項目中,應從
'react-router-dom'
導入generatePath
函數
這個演示頁面展示了generatePath
的基本用法和常見場景,我們可以通過修改路徑模式和參數來實時查看生成的結果。請注意,這是一個簡化版的實現,實際應用中應使用React Router提供的正式函數。