目錄
一、腳手架基礎語法(16~17)
1.1、hello react
1.2、組件樣式隔離(樣式模塊化)
1.3、react插件
二、React Router v5
2.1、react-router-dom相關API
2.1.1、內置組件
2.1.1.1、BrowserRouter
2.1.1.2、HashRouter
2.1.1.3、Route
2.1.1.4、Redirect
2.1.1.5、Link
2.1.1.7、Switch
2.1.2、其它
2.1.2.1、history對象
2.1.2.2、match對象
2.1.2.3、withRouter對象
2.2、向路由組件傳參
2.2.1、傳遞params參數
2.2.2、傳遞search參數
2.2.3、傳遞state參數
2.3、編程式路由導航跳轉
三、React Router v6
3.1、一級路由
3.2、重定向
3.4、useRoutes
3.5、嵌套路由
3.6、路由傳參
3.6.1、params
3.6.2、search
3.6.3、state
3.7、編程式路由導航
3.8、use拓展
四、V6 pk?V5
一、腳手架基礎語法(16~17)
1.1、hello react
1.2、組件樣式隔離(樣式模塊化)
已知:vue2通過scoped來防止組件樣式沖突
react解決方法:樣式模塊化(CSS Modules)
使用方法:
1、將?CSS?文件命名為?[name].module.css。
2、在組件中導入樣式模塊,并使用對象屬性訪問樣式類名。
import "./hello.css";//直接引入
import styles from "./hello.module.css";//樣式模塊化
<h2 className={styles.title}>hello react!</h2>
補充:Styled Components、Emotion、Shadow DOM 和 CSS 命名空間等方案也可以。
1.3、react插件
VScode插件搜索react:ES7+ React/Redux/React-Native snippets
輸入rcc:類組件? ?rfc:函數組件回車即可
更多快捷代碼塊:vscode-react-javascript-snippets/docs/Snippets.md at 185bb91a0b692c54136663464e8225872c434637 · r5n-labs/vscode-react-javascript-snippets · GitHub
二、React Router v5
1、SPA:單頁面應用
? ? ? (1)、點擊頁面中的鏈接不會刷新頁面,只做頁面的局部刷新
? ? ? (2)、數據都通過ajax請求獲取,并在前端異步展現
2、路由:一個路由就是一個映射關系(key:value)
? ? ? key為路徑,value可能是function【后端路由】或component【前端路由】
? ? ? 前端:當瀏覽器的path變為/XX時,當前路由組件就會變為XX組件,依賴瀏覽器的
hash
或history
API來管理 URL 狀態。
2.1、react-router-dom相關API
下載:npm i?react-router-dom@5
路由組件和一般組件接收的props不同,前者會接收到三個history、location、match固定屬性。
2.1.1、內置組件
import { BrowserRouter as Router, Route, Switch, Redirect,Link } from 'react-router-dom'
export default class App extends Component {render() {return (<div><Router>
{/* Switch雖然在v5版本不是必須的,但是基本都會用到,只讓頁面匹配上一個,不能匹配上多個 */}<Switch>
<Route path='/' exact render={() => <Redirect to='/index'></Redirect>}></Route>
<Route path='/index' render={(props) => {
//想要進入到主頁,如果此時還未登錄就重定向到登錄頁,如果已經登陸了就進入首頁if (isLogin()) {
// Home組件并不是路由組件,render的函數式組件才是真正的路由組件,需要把props的內容傳到Home組件中。return <Home {...props}></Home>} else {return <Redirect to='/login'></Redirect>}
}}></Route>
<Route path='/login' render={(props) => {if (isLogin()) {return <Redirect to='/index/home'></Redirect>} else {return <Login {...props}></Login>}
}}></Route></Switch><div className="left-side"><Link to="/about">About</Link><Link to="/home">Home</Link></div><div className="right-content"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></Router></div>)}
}
2.1.1.1、BrowserRouter
使用?HTML5?history?API?來保持URL?路徑不帶?#,適合現代?Web?應用
2.1.1.2、HashRouter
使用?#?來管理?URL,適合不支持HTML5?history?API的老版本瀏覽器,刷新后會導致路由參數丟失
2.1.1.3、Route
<Route>
?:用于定義路徑和對應組件的基本單元
<Route path="/home" component={<Home />} />
2.1.1.4、Redirect
重定向:<Redirect to='/index'></Redirect>
2.1.1.5、Link
它是React Router提供的用于頁面跳轉的組件,類似于HTML的<a>
標簽,但不會引起頁面刷新
2.1.1.6、NavLink
特殊的<Link>,
添加了活動樣式(activeClassName),通過this.props.children獲取標簽體內容
<NavLink to="/home" activeClassName="active">Go to Home</NavLink>
2.1.1.7、Switch
只讓頁面匹配上一個,不能匹配上多個,提高路由匹配效率
拓展:
? ? ? ? 路由默認使用模糊匹配,如果開啟嚴格匹配【exact={true}】的話,有時會導致無法繼續匹配二級路由,不要隨便開啟。
2.1.2、其它
2.1.2.1、history對象
管理瀏覽器的會話歷史。例如推送新的路徑、替換當前路徑和返回上一頁等處理導航的方法。
const history = useHistory();const handleNavigation = () => {history.push('/new-path'); // 導航到新的路徑};
2.1.2.2、match對象
包含了與當前路由匹配的信息,它通常在路由組件中作為 props 傳遞。
const User = ({ match }) => {return <div>User ID: {match.params.userId}</div>;
};
const App = () => (<Route path="/users/:userId" component={User} />
);
2.1.2.3、withRouter對象
高階組件,用于將history、location?和match對象作為props傳遞給包裝的組件,將一般組件加工,讓其具備路由組件所特有的API。
const MyComponent = ({ history, location, match }) => {const handleNavigation = () => {history.push('/new-path'); // 導航到新的路徑};return (<div><h1>Current Path: {location.pathname}</h1><button onClick={handleNavigation}>Go to New Path</button></div>);
};
export default withRouter(MyComponent);
類組件應用路由跳轉:
import React from 'react';
import { withRouter } from 'react-router-dom';
class MyComponent extends React.Component {handleNavigate = () => {const { history } = this.props;history.push('/new-route');};render() {return (<div><button onClick={this.handleNavigate}>Go to New Route</button></div>);}
}
export default withRouter(MyComponent);
2.2、向路由組件傳參
2.2.1、傳遞params參數
類組件 :
函數組件:
const User = ({ match }) => {const { userId } = match.params;return <div>User ID: {userId}</div>;
};
2.2.2、傳遞search參數
類組件 :
函數組件:
import { useLocation } from 'react-router-dom';
const User = () => {const location = useLocation();const searchParams = new URLSearchParams(location.search);const name = searchParams.get('name');const age = searchParams.get('age');return (<div><p>Name: {name}</p><p>Age: {age}</p></div>);
};
2.2.3、傳遞state參數
類組件:
函數組件:
import { useLocation } from 'react-router-dom';
const User = () => {const location = useLocation();const { id,title } = location.state || {};return (<div><p>From Dashboard: {id}---{title}</p></div>);
};
總結:
1、params:通過路由路徑傳遞參數,使用match.params接收。
2、search:通過查詢字符串傳遞參數,使用location.search和qs.parse【基于類組件】、location.search和URLSearchParams【基于函數組件】接收。
3、state:通過history.push或Link的to屬性傳遞任意對象,使用location.state接收。補充:useHistory、useLocation、useParams等Hook在React?16.8之后才可用,并通過withRouterHOC進行路由的高階組件包裝。
2.3、編程式路由導航跳轉
函數組件:
import React from 'react';
import { useHistory } from 'react-router-dom';
const MyComponent = () => {const history = useHistory(); // 獲取 history 對象const handleNavigate = () => {history.push('/new-route');};return (<div><button onClick={handleNavigate}>Go to New Route</button></div>);
};
export default MyComponent;
類組件:
<button onClick={() => this.pushShow(item.id, item.title)}>push查看</button>
<button onClick={() => this.replaceShow(item.id, item.title)}>replace查看</button>
replaceShow = (id, title) => {this.props.history.replace(`/homes/message/detail/${id}/${title}`);this.props.history.replace(`/homes/message/detail/?id=${id}/title=${title}`);this.props.history.replace(`/homes/message/detail`,{id,title});};
pushShow = (id, title) => {this.props.history.push(`/homes/message/detail/${id}/${title}`);this.props.history.push(`/homes/message/detail/?id=${id}/title=${title}`);this.props.history.push(`/homes/message/detail`,{id,title});};
三、React Router v6
下載:npm i?react-router-dom@6
3.1、一級路由
Routes:
它用來包裹所有的<Route>,
并且確保只渲染匹配的第一個 <Route>
<Routes><Route path="/" element={<Home />} /><Route path="/about" element={<About />} />
</Routes>
3.2、重定向
<Route path="/" element={<Navigate to="/about" />}></Route>
3.3、NavLink高亮
function computedClassName({ isActive }) {return isActive ? "list-item active" : "list-item";
}
<NavLink className={computedClassName} to="/about">About</NavLink>
<NavLink className={computedClassName} to="/homes">Home</NavLink>
3.4、useRoutes
3.5、嵌套路由
<Outlet?/>是一個占位符組件,用來渲染匹配的子路由的內容,父路由通常會渲染一個包含
<Outlet />
的組件,這樣它就可以根據當前的 URL 渲染子路由對應的組件。
3.6、路由傳參
3.6.1、params
<Route path="/user/:id" element={<UserProfile />} />
// UserProfile 組件中接收 params 參數
import { useParams } from 'react-router-dom';
const UserProfile = () => {const { id } = useParams();return <div>User ID: {id}</div>;
};
3.6.2、search
const [searchParams] = useSearchParams();const q = searchParams.get("q"); // 獲取查詢參數 'q'const page = searchParams.get("page"); // 獲取查詢參數 'page'return (<div><h1>搜索結果</h1><p>查詢關鍵詞:{q}</p><p>當前頁碼:{page}</p></div>);
<Link to="/search?keyword=react">搜索React</Link>
// 在組件中接收查詢參數
import { useLocation } from 'react-router-dom';
const Search = () => {const location = useLocation();const query = new URLSearchParams(location.search);const keyword = query.get("keyword");return <div>搜索關鍵詞:{keyword}</div>;
};
3.6.3、state
<Link to={{ pathname: '/detail', state: { id: 1, name: 'React' } }}>詳情</Link>
// 在目標組件中接收 state 參數
import { useLocation } from 'react-router-dom';
const Detail = () => {const location = useLocation();const { id, name } = location.state || {};return (<div><p>ID:{id}----------名稱:{name}</p></div>);
};
總結:
1、params:通過路由路徑傳遞參數,使用useParams鉤子接收。
2、search:通過查詢字符串傳遞參數,使用useSearchParams或者useLocation和URLSearchParams解析。
3、state:通過Link或useNavigate傳遞狀態參數,使用useLocation.state?來接收。
3.7、編程式路由導航
const navigate = useNavigate();const handleClick = () => {// 導航到 "/about" 頁面,state參數寫在對象里,params與search參數之間寫url里navigate('/about', { state: { fromDashboard: true } });};
3.8、use拓展
useInRouterContext:檢查組件是否在路由上下文中。
useNavigationType:獲取當前導航類型(POP、PUSH、REPLACE)。
useOutlet:在父路由中渲染子路由的元素。
useResolvedPath:解析路徑并返回路徑對象
四、V6 pk?V5
V6相比V5,進行了以下改動:
1、Routes代替了Switch、Navigate代替了Redirect;
2、useNavigate代替了useHistory,新增useParams、useLocation等,官方推薦函數組件。
3、路由匹配變得更精確,支持嵌套路由和動態路由的定義。
4、Route?組件的?API?也發生了改變,不再需要?component?或?render?屬性,使用element?屬性來傳遞渲染的組件。若項目使用的是React?16.3 ~16.7,只能使用React?Router?v5。
若項目使用的是?React?16.8?或更高版本,可以選擇React?Router?v5或React?Router?v6,但建議使用v6,因為它包含了最新的功能和更簡潔的?API。