React插槽路由
Jdoit CW 人气:1内容
清楚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个对象,进行路径的设置。Link
的replace属性
:点击链接后,将新地址替换成历史访问记录的原地址
。
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 使用步骤
- 安装
redux
:npm 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 建立连接时:数据映射要写在方法映射之前(否则无法拿到数据)。
加油
加载全部内容