React從插槽、路由、redux的詳細(xì)過程
內(nèi)容
清楚React 插槽
弄明白R(shí)eact 路由
會(huì)使用 redux 及 react-redux
1. React 插槽
組建中寫入內(nèi)容,這些內(nèi)容可以被識(shí)別和控制。React需要自己開發(fā)支持插槽功能。原理:父組件組件中寫入的HTML,可以傳入子組件的props中。
1.組件中的HTML內(nèi)容直接全部插入

2.組件中根據(jù)HTML內(nèi)容的不同,插入的位置不同

示例:
class AppCom extends React.Component{
constructor(props){
super(props);
this.state = {}
}
render(){
return(
<div>
<h1>我是App根組件</h1>
<h1>-----------------</h1>
<SlotCom>
<h3>我是插槽內(nèi)的文字1</h3>
<h3>我是插槽內(nèi)的文字2</h3>
<h3>我是插槽內(nèi)的文字3</h3>
</SlotCom>
<h1>------------------</h1>
<SlotChangeCom>
<h2 className="header">Header</h2>
<h2 className="main">Main</h2>
<h2 className="footer">Footer</h2>
</SlotChangeCom>
</div>
)
}
}
class SlotCom extends React.Component{ //組件中HTML內(nèi)容直接全部插入
render(){
console.log(this.props)
return(
<div>
{this.props.children}
</div>
)
}
}
class SlotChangeCom extends React.Component{ //組件中HTML內(nèi)容不同,插入位置不同(注意此處的值也可自定義,均可早props中拿到)
render(){
console.log(this.props)
let HeaderCom,MainCom,FooterCom;
this.props.children.forEach((item,index)=>{
if(item.props['className'] === 'header'){
HeaderCom = item
}else if(item.props['className'] === 'main'){
MainCom = item
}else{
FooterCom = item
}
})
return(
<div>
<div>
{HeaderCom}
</div>
<div>
{MainCom}
</div>
<div>
{FooterCom}
</div>
</div>
)
}
}
2. React 路由
根據(jù)不同的路徑,顯示不同的組件(內(nèi)容);React使用的庫react-router-dom;
2.1 安裝庫
npm install react-router-dom --save
2.2 ReactRouter三大組件
- Router:所有
路由組件的根組件(底層組件),包裹路由規(guī)則的最外層容器。 - 屬性:
basename->設(shè)置當(dāng)前路由根路徑,router可以在1個(gè)組件中寫多個(gè)。 - Link:
路由跳轉(zhuǎn)的組件,主要配合 to實(shí)現(xiàn)路由跳轉(zhuǎn)。 - Route:路由
規(guī)則匹配組件,顯示當(dāng)前規(guī)則對(duì)應(yīng)的組件。
2.3 路由其他方法
- 如果要
精確匹配,那么可以在route上設(shè)置exact屬性。 Link組件可以設(shè)置to屬性來進(jìn)行頁面的跳轉(zhuǎn),to屬性可以直接寫路徑的字符串,也可以通過1個(gè)對(duì)象,進(jìn)行路徑的設(shè)置。Link的replace屬性:點(diǎn)擊鏈接后,將新地址替換成歷史訪問記錄的原地址。
2.4 重定向組件
如果訪問某個(gè)組件時(shí),如果有重定向組件,那么就會(huì)修改頁面路徑,使得頁面內(nèi)容顯示為所定向路徑的內(nèi)容
<Redirect><Redirect>
2.5 Switch組件
讓switch組件內(nèi)容的route只匹配1個(gè),只要匹配到了,剩余的路由規(guī)則將不再匹配
注意:Switch 組件只能包裹在 Route組件外面
2.6 示例
1.效果

2.代碼
import React from 'react';
import './index.css';
// import {HashRouter as Router,Link,Route} from 'react-router-dom';//哈希模式
import {BrowserRouter as Router,Link,Route,Redirect,Switch} from 'react-router-dom';//history模式
function One(){ //定義單個(gè)組件做演示
return(
<h1>我是ONE</h1>
)
}
function Two(){
return(
<h1>我是TWO</h1>
)
}
function Three(props){
console.log(props) //接收傳遞的參數(shù)
return(
<h1>我是THREE</h1>
)
}
function News(props){
console.log(props.match.params.id)//拿到動(dòng)態(tài)路由傳遞的參數(shù)
return(
<h1>我是動(dòng)態(tài)路由頁</h1>
)
}
function GoTwo(){
return(
<Redirect to="/two"></Redirect>
)
}
class RouterCom extends React.Component{
constructor(props){
super(props)
this.state = {
}
}
render(){
let threeObj = {
pathname:'/three', //傳入的路徑
search:'?id=1',//get請(qǐng)求參數(shù)
hash:'#three',//設(shè)置Hash值
state:{msg:'hello world'} // 傳入組件的數(shù)據(jù)
}
return(
<div>
<Router>{/* Router 含有basename屬性,表示基礎(chǔ)路徑 自動(dòng)加上basename 的值;用其可進(jìn)行嵌套子路由 */}
<div className="tab">
<Link to="/one">ONE</Link>
<Link to="/two">TWO</Link>
<Link to={threeObj} replace>THREE</Link>
<Link to="/news/2">NEWS</Link>
<Link to="/gotwo">goTwo</Link>
</div>
<Switch>
<Route path="/one" exact component={One}></Route>
<Route path="/one" exact component={One}></Route>
<Route path="/two" exact component={Two}></Route>
<Route path="/three" exact component={Three}></Route>
<Route path="/news/:id" exact component={News}></Route>
<Route path="/gotwo" exact component={GoTwo}></Route>
</Switch>
</Router>
</div>
)
}
}
export default RouterCom
3. redux
解決React數(shù)據(jù)管理(狀態(tài)管理),用于中大型,數(shù)據(jù)比較龐大,組件之間數(shù)據(jù)交互多的情況下使用。如果你不知道是否需要使用Redux,那么你就不需要用它!
3.1 主要作用
- 解決組件的
數(shù)據(jù)通信。 - 解決
數(shù)據(jù)和交互較多的應(yīng)用
Redux只是一種狀態(tài)管理的解決方案!
Store:數(shù)據(jù)倉庫,保存數(shù)據(jù)的地方。
State:state:是1個(gè)對(duì)象,數(shù)據(jù)倉庫里的所有數(shù)據(jù)都放到1個(gè)state里。
Action:1個(gè)動(dòng)作,觸發(fā)數(shù)據(jù)改變的方法。
Dispatch:將動(dòng)作觸發(fā)成方法。
Reducer:是1個(gè)函數(shù),通過獲取動(dòng)作,改變數(shù)據(jù),生成1個(gè)新state。從而改變頁面。
3.2 使用步驟
- 安裝
redux:npm install redux - 創(chuàng)建
reducer函數(shù) - 創(chuàng)建倉庫修改數(shù)據(jù)(通過動(dòng)作修改數(shù)據(jù))
- 獲取數(shù)據(jù)
- 修改視圖(監(jiān)聽數(shù)據(jù)的變化,重新渲染內(nèi)容)
示例:
預(yù)覽:

代碼:
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
class ComputerCom extends React.Component{ // 創(chuàng)建需要展示數(shù)據(jù)的組件
render(){
let state = store.getState(); // 通過getState() 方法獲取 Store 里的值
return(
<div>
<h1>Store里邊的數(shù):{state.num}</h1>
<button onClick={add}>自加 1</button>
<button onClick={subtraction}>自減 1</button>
</div>
)
}
}
function reducer(state={num:0},action){ //Reducer:是1個(gè)函數(shù)(初始化數(shù)據(jù)),通過獲取動(dòng)作,改變數(shù)據(jù),生成1個(gè)新state。從而改變頁面
switch(action.type){
case "add":
state.num++
break;
case "subtraction":
state.num--;
break;
default:
break;
}
return {...state} // 此處返回相當(dāng)于 對(duì)象的 copy
}
const store = createStore(reducer); //創(chuàng)建倉庫(必須傳入reducer)
//定義要操作的方法
function add(){
store.dispatch({type:"add"}) //通過倉庫的方法dispatch進(jìn)行修改數(shù)據(jù)
// store.dispatch({type:"add",content:{id:1,msg:"helloworld"}}) 也可在修改數(shù)據(jù)時(shí)傳入?yún)?shù)
}
function subtraction(){
store.dispatch({type:"subtraction"}) //通過倉庫的方法dispatch進(jìn)行修改數(shù)據(jù)
}
ReactDOM.render(<ComputerCom></ComputerCom>,document.querySelector("#root"))
// 通過store.subsctibe() 方法(必須傳入函數(shù)) 修改視圖(監(jiān)聽數(shù)據(jù)的變化,重新渲染內(nèi)容)
store.subscribe(()=>{
ReactDOM.render(<ComputerCom></ComputerCom>,document.querySelector("#root"))
})
注意:所有的數(shù)據(jù)操作均在 reducer 中完成,其他函數(shù)不可修改數(shù)據(jù),只能 將動(dòng)作觸發(fā)成方法
4. react-redux
react-redux 是對(duì)redux 的進(jìn)一步完善,它避免了redux 每次修改數(shù)據(jù)都要調(diào)用渲染函數(shù)的弊端
4.1 基本概念
安裝:npm install react-redux 注意,使用時(shí)還要安裝 redux
Provider組件:自動(dòng)的將store里的state和組件進(jìn)行關(guān)聯(lián)。
MapStatetoProps:這個(gè)函數(shù)用于將store的state映射到組件的props里,實(shí)現(xiàn)數(shù)據(jù)共享。(函數(shù)名自定義)
mapdispatchToProps:將store中的dispatch映射到組件的props里,實(shí)現(xiàn)了方法的共享。(函數(shù)名自定義)
Connect方法:將組件和數(shù)據(jù)(方法)進(jìn)行連接。
示例(執(zhí)行結(jié)果與redux 演示同):
import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';
import {connect,Provider} from 'react-redux';
class ComputedCom extends React.Component{
render(){
// 倉庫的數(shù)據(jù),通過store 的state 傳給props ,直接通過props 就可以獲取 state的數(shù)據(jù)
const value = this.props.value;
// 將修改數(shù)據(jù)的方法傳入到props中(等同于vuex 的 mapMutation 映射)
const clickAdd = this.props.clickAdd;
const clickSub = this.props.clickSub;
return(
<div>
<h1>Store里面的數(shù):{value}</h1>
<button onClick={clickAdd}>自加1</button>
<button onClick={clickSub}>自減1</button>
</div>
)
}
}
let actionObj = {
add:function(state,action){
state.num++;
return state
},
sub:function(state,action){
state.num = state.num + action.num; // action.num 接收傳遞的參數(shù)
return state
}
}
function reducer(state={num:0},action){ // # Reducer:是1個(gè)函數(shù)(初始化數(shù)據(jù)),通過獲取動(dòng)作,改變數(shù)據(jù),生成1個(gè)新state。從而改變頁面
// 如果方法過多,可以把它寫在外面
/* switch(action.type){
case "add":
state.num++
break;
case "sub":
state.num--;
break;
default:
break;
} */
if(action.type.indexOf('redux') === -1){ //判斷數(shù)據(jù)是否初始化,若無初始化,先初始化
state = actionObj[action.type](state,action);
return {...state} //# 狀態(tài)結(jié)構(gòu),防止哈希值相同,不進(jìn)行解析
}else{
return state
}
}
const store = createStore(reducer); // 創(chuàng)建倉庫
function mapStateToProps(state){ //# 將數(shù)據(jù)映射到props(映射函數(shù)的形參固定)
return{
value:state.num
}
}
// 將修改state 數(shù)據(jù)的方法,映射到props,默認(rèn)會(huì)將 store.dispatch() 作為參數(shù)
function mapDispatchToProps(dispatch){
return{
clickAdd:()=>{dispatch({type:"add"})},
clickSub:()=>{dispatch({type:"sub",num:-1})} //向action 傳值
}
}
// 將數(shù)據(jù)倉庫的state 和 修改state 的方法映射到新的組件上,形成新的組件(讓數(shù)據(jù)、方法、組件形成關(guān)聯(lián))
const App = connect(
mapStateToProps, //# 切記數(shù)據(jù)映射要寫在方法映射之前(否則無法拿到數(shù)據(jù))
mapDispatchToProps,
)(ComputedCom)
ReactDOM.render(
<Provider store={store}>
<App/>
</Provider>,
document.querySelector('#root')
)
注意:①:返回狀態(tài)數(shù)據(jù)時(shí)要解構(gòu):防止哈希值相同,不進(jìn)行解析;②:將數(shù)據(jù)映射到props(映射函數(shù)的形參固定,函數(shù)名可自定義);③:切記用 connect 建立連接時(shí):數(shù)據(jù)映射要寫在方法映射之前(否則無法拿到數(shù)據(jù))。
加油
到此這篇關(guān)于React從插槽、路由、redux的詳細(xì)過程的文章就介紹到這了,更多相關(guān)React插槽路由內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
React Ref Callback使用場(chǎng)景最佳實(shí)踐詳解
這篇文章主要為大家介紹了React Ref Callback使用場(chǎng)景最佳實(shí)踐詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
ReactQuery系列React?Query?實(shí)踐示例詳解
這篇文章主要為大家介紹了ReactQuery系列React?Query?實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
ReactJS?應(yīng)用兼容ios9對(duì)標(biāo)ie11解決方案
這篇文章主要為大家介紹了ReactJS?應(yīng)用兼容ios9對(duì)標(biāo)ie11解決方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
react 國(guó)際化的實(shí)現(xiàn)代碼示例
這篇文章主要介紹了react 國(guó)際化的實(shí)現(xiàn)代碼示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09
React中useCallback useMemo到底該怎么用
在React函數(shù)組件中,當(dāng)組件中的props發(fā)生變化時(shí),默認(rèn)情況下整個(gè)組件都會(huì)重新渲染。換句話說,如果組件中的任何值更新,整個(gè)組件將重新渲染,包括沒有更改values/props的函數(shù)/組件。在react中,我們可以通過memo,useMemo以及useCallback來防止子組件的rerender2023-02-02
淺談react.js中實(shí)現(xiàn)tab吸頂效果的問題
下面小編就為大家?guī)硪黄獪\談react.js中實(shí)現(xiàn)tab吸頂效果的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-09-09

