日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

React從插槽、路由、redux的詳細過程_React

作者:Jdoit?CW ? 更新時間: 2022-11-26 編程語言

內容

清楚React 插槽
弄明白React 路由
會使用 redux 及 react-redux

1. React 插槽

組建中寫入內容,這些內容可以被識別和控制。React需要自己開發支持插槽功能。原理:父組件組件中寫入的HTML,可以傳入子組件的props中。

1.組件中的HTML內容直接全部插入

在這里插入圖片描述

2.組件中根據HTML內容的不同,插入的位置不同

在這里插入圖片描述

示例:

class AppCom extends React.Component{
    constructor(props){
        super(props);
        this.state = {}
    }
    render(){
        return(
            <div>
                <h1>我是App根組件</h1>
                <h1>-----------------</h1>
                <SlotCom>
                <h3>我是插槽內的文字1</h3>
                <h3>我是插槽內的文字2</h3>
                <h3>我是插槽內的文字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內容直接全部插入
    render(){
        console.log(this.props)
        return(
            <div>
                {this.props.children}
            </div>
        )
    }
}

class SlotChangeCom extends React.Component{    //組件中HTML內容不同,插入位置不同(注意此處的值也可自定義,均可早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 路由

根據不同的路徑,顯示不同的組件(內容);React使用的庫react-router-dom;

2.1 安裝庫

npm install react-router-dom --save

2.2 ReactRouter三大組件

  • Router:所有路由組件的根組件(底層組件),包裹路由規則的最外層容器
  • 屬性:basename->設置當前路由根路徑,router可以在1個組件中寫多個。
  • Link路由跳轉的組件,主要配合 to 實現路由跳轉。
  • Route:路由規則匹配組件,顯示當前規則對應的組件。

2.3 路由其他方法

  • 如果要精確匹配,那么可以在route上設置exact屬性
  • Link組件可以設置to屬性來進行頁面的跳轉,to屬性可以直接寫路徑的字符串,也可以通過1個對象,進行路徑的設置。
  • Linkreplace屬性:點擊鏈接后,將新地址替換成歷史訪問記錄的原地址

2.4 重定向組件

如果訪問某個組件時,如果有重定向組件,那么就會修改頁面路徑,使得頁面內容顯示為所定向路徑的內容

<Redirect><Redirect>

2.5 Switch組件

讓switch組件內容的route只匹配1個,只要匹配到了,剩余的路由規則將不再匹配

注意: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(){ //定義單個組件做演示
    return(
        <h1>我是ONE</h1>
    )
}
function Two(){
    return(
        <h1>我是TWO</h1>
    )
}
function Three(props){
    console.log(props)  //接收傳遞的參數
    return(
        <h1>我是THREE</h1>
    )
}
function News(props){
    console.log(props.match.params.id)//拿到動態路由傳遞的參數
    return(
        <h1>我是動態路由頁</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請求參數
            hash:'#three',//設置Hash值
            state:{msg:'hello world'} // 傳入組件的數據
        }
        return(
            <div>
                <Router>{/*  Router 含有basename屬性,表示基礎路徑 自動加上basename 的值;用其可進行嵌套子路由 */}
                    <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數據管理(狀態管理),用于中大型,數據比較龐大,組件之間數據交互多的情況下使用。如果你不知道是否需要使用Redux,那么你就不需要用它!

3.1 主要作用

  • 解決組件的數據通信
  • 解決數據和交互較多的應用

Redux只是一種狀態管理的解決方案!

Store:數據倉庫,保存數據的地方
State:state:是1個對象,數據倉庫里的所有數據都放到1個state里
Action:1個動作觸發數據改變的方法
Dispatch將動作觸發成方法
Reducer:是1個函數,通過獲取動作,改變數據,生成1個新state。從而改變頁面。

3.2 使用步驟

  • 安裝 reduxnpm install redux
  • 創建 reducer 函數
  • 創建倉庫修改數據(通過動作修改數據)
  • 獲取數據
  • 修改視圖(監聽數據的變化,重新渲染內容)

示例:

預覽:

在這里插入圖片描述

代碼:

import React from 'react';
import ReactDOM from 'react-dom';
import {createStore} from 'redux';

class ComputerCom extends React.Component{ // 創建需要展示數據的組件
    render(){
        let state = store.getState(); // 通過getState() 方法獲取 Store 里的值
        return(
            <div>
                <h1>Store里邊的數:{state.num}</h1>
                <button onClick={add}>自加 1</button>
                <button onClick={subtraction}>自減 1</button>
            </div>
        )
    }
}

function reducer(state={num:0},action){  //Reducer:是1個函數(初始化數據),通過獲取動作,改變數據,生成1個新state。從而改變頁面
    switch(action.type){
        case "add":
            state.num++
            break;
        case "subtraction":
            state.num--;
            break;
        default:
            break;
    }
    return {...state}  // 此處返回相當于 對象的 copy
}

const store = createStore(reducer); //創建倉庫(必須傳入reducer)

//定義要操作的方法
function add(){
    store.dispatch({type:"add"})  //通過倉庫的方法dispatch進行修改數據
    // store.dispatch({type:"add",content:{id:1,msg:"helloworld"}})  也可在修改數據時傳入參數
}

function subtraction(){
    store.dispatch({type:"subtraction"})  //通過倉庫的方法dispatch進行修改數據
}

ReactDOM.render(<ComputerCom></ComputerCom>,document.querySelector("#root"))

// 通過store.subsctibe() 方法(必須傳入函數) 修改視圖(監聽數據的變化,重新渲染內容)
store.subscribe(()=>{
    ReactDOM.render(<ComputerCom></ComputerCom>,document.querySelector("#root"))
})

注意:所有的數據操作均在 reducer 中完成,其他函數不可修改數據,只能 將動作觸發成方法

4. react-redux

react-redux 是對redux 的進一步完善,它避免了redux 每次修改數據都要調用渲染函數的弊端

4.1 基本概念

安裝:npm install react-redux 注意,使用時還要安裝 redux

Provider組件自動的將store里的state和組件進行關聯
MapStatetoProps:這個函數用于將store的state映射到組件的props里,實現數據共享。(函數名自定義)
mapdispatchToProps將store中的dispatch映射到組件的props里,實現了方法的共享。(函數名自定義)
Connect方法:將組件和數據(方法)進行連接

示例(執行結果與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(){
        // 倉庫的數據,通過store 的state 傳給props ,直接通過props 就可以獲取 state的數據
        const value = this.props.value;
        // 將修改數據的方法傳入到props中(等同于vuex 的 mapMutation 映射)
        const clickAdd = this.props.clickAdd;
        const clickSub = this.props.clickSub;
        return(
            <div>
                <h1>Store里面的數:{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 接收傳遞的參數
        return state
    }
}
function reducer(state={num:0},action){  // # Reducer:是1個函數(初始化數據),通過獲取動作,改變數據,生成1個新state。從而改變頁面
    // 如果方法過多,可以把它寫在外面
   /*  switch(action.type){
        case "add":
            state.num++
            break;
        case "sub":
            state.num--;
            break;
        default:
            break;
    } */
    if(action.type.indexOf('redux') === -1){    //判斷數據是否初始化,若無初始化,先初始化
        state = actionObj[action.type](state,action);
        return {...state} //# 狀態結構,防止哈希值相同,不進行解析
    }else{
        return state
    }  
}

const store = createStore(reducer);  // 創建倉庫

function mapStateToProps(state){  //# 將數據映射到props(映射函數的形參固定)
    return{
        value:state.num
    }
}
// 將修改state 數據的方法,映射到props,默認會將 store.dispatch() 作為參數
function mapDispatchToProps(dispatch){
    return{
        clickAdd:()=>{dispatch({type:"add"})},
        clickSub:()=>{dispatch({type:"sub",num:-1})}  //向action 傳值
    }
}
// 將數據倉庫的state 和 修改state 的方法映射到新的組件上,形成新的組件(讓數據、方法、組件形成關聯)
const App = connect(
    mapStateToProps, //# 切記數據映射要寫在方法映射之前(否則無法拿到數據)
    mapDispatchToProps,
)(ComputedCom)

ReactDOM.render(
    <Provider store={store}>
        <App/>
    </Provider>,
    document.querySelector('#root')
)

注意:①:返回狀態數據時要解構:防止哈希值相同,不進行解析;②:將數據映射到props(映射函數的形參固定,函數名可自定義);③:切記用 connect 建立連接時:數據映射要寫在方法映射之前(否則無法拿到數據)。

加油

原文鏈接:https://jdoit-cw.blog.csdn.net/article/details/108210113

欄目分類
最近更新