当前位置: 首页 > Web前端 > HTML5

React、react-router、redux可能是最好的小实践2

时间:2023-04-04 23:56:03 HTML5

上一篇:react、react-router、redux可能是最好的小实践1添加reduxReact实现组件间数据循环。更准确地说,这叫做“单向数据流”——数据从一个方向从父组件流向子组件。由于这个特性,在没有父子关系的两个组件之间交换数据变得不那么明显。这里Redux就派上用场了。Redux通过将应用程序的所有状态存储在一个称为“存储”的位置来提供解决方案。然后组件可以将状态更改“分发”到商店,而不是直接与其他组件通信。所有组件都应该知道可以“订阅”商店的状态变化。如下图所示:说完原理,我们开始添加代码。我们先来看一个小例子。在开始之前,您需要使用Redux.createStore()创建一个存储,然后将所有的reducer作为参数传入。让我们来看看这个只传递一个reducer的小例子:varuserReducer=function(state,action){if(state===undefined){state=[];}if(action.type==='ADD_USER'){state.push(action.user);}returnstate;}varstore=Redux.createStore(userReducer);store.dispatch({type:'ADD_USER',user:{name:'xiaoming'}});上面的程序做了什么:这个store只是由一个reducer创建的。这个reducer用一个空数组初始化它的状态。*新的用户对象用于调度的动作。reducer将新用户对象附加到状态并将其返回以更新存储。*在这个例子中,reducer实际上被调用了两次——一次是在创建store时,一次是在调度action之后。当store被创建时,Redux立即调用所有reducer,并使用它们的返回值作为初始状态。对reducer的第一次调用为状态传递了一个undefined。经过reducer内部的代码处理后,返回一个空数组作为store的状态作为开始。在分派每个动作后调用所有减速器。因为reducer返回的状态将成为存储在store中的新状态,Redux总是期望所有的reducer都返回一个状态。在此示例中,reducer的第二次调用发生在分派之后。请记住,分派的操作描述了更改状态的意图,并且通常携带用于更新状态的数据。这一次,Redux将当前状态(仍然是一个空数组)与action对象一起传递给reducer。action对象现在有一个值为1ADD_USER的type属性,让reducer知道如何更改状态。redux正式登场在src下创建一个redux,actions,data(存放一些初始数据)文件夹,然后在data文件夹下创建一个db.js,在这个文件中写入一些初始数据:src/data/db.jsconstdata=[{id:1,title:'明天我要打酱油',content:'一起打酱油吧'},{id:2,title:'周末去书店',content:'书是人类进步的阶梯'},{id:3,title:'备份数据库',content:'备份服务器的数据库,一般是独立的,分布式的数据库'},{id:4,title:'周五记得洗被子',content:'洗杯被子被子被子'},{id:5,title:'Plan5',content:'Plan5content'}]exportdefaultdataOk,初始数据我们有了它,下面就是创建一个store。在redux文件夹下,创建一个planlist.js文件。这个文件就是operationstore的action动作集合处理后的数据。这个时候我们在action文件夹下新建一个,action-type.js和plan.js,代码如下:src/action/action-type.jsexportconstADD='ADD';exportconstDELECT='DELECT';exportconstSHOW='SHOW';src/action/plan.jsimport*astypesfrom'./action-type.js';//添加计划导出函数addPlan(item){return{type:types.ADD,item};}//删除计划导出函数deleteplan(id){return{type:types.DELECT,id};}//显示和隐藏弹出层导出函数show(show){return{type:types.SHOW,show};}action我们都定义好了现在我们可以换店了编写我们的reducersrc/redux/planlist.jsimport*astypesfrom'../actions/action-type.js';importdatafrom'../data/db.js'constinitialState={show:false,//是否显示弹出的计划列表:data//初始计划列表};constplanReducer=function(state=initialState,action){letlist=state.planlist;switch(action.type){//添加计划案例types.ADD:list.push(action.item);返回Object.assign({},state,{planlist:list});//删除计划案例types.DELECT:letnewstate=list.filter((item)=>item.id!=action.id);返回Object.assign({},state,{planlist:newstate});//显示和隐藏弹出层casetypes.SHOW:returnObject.assign({},state,{show:action.show});}returnstate;}exportdefaultplanReducer;在redux下创建reducers.js和store.js,src/redux/reducers.jsimport{combineReducers}from'redux';//Reducersimportplanlistfrom'./planlist';//合并Reducersvarreducers=combineReducers({planlist:planlist});导出默认值ultreducers;src/redux/store.jsimport{createStore}from'redux';importreducersfrom'./reducers.js';conststore=createStore(reducers);exportdefaultstore;这将完全创建我们的商店下面是把store和我们的组件完全结合起来,这里用到了react-redux的connect模块。这个东西是连接组件和商店的模块。然后,App.js加入我们的。storesrc/App.jsimportReact,{Component}from'react'import{BrowserRouterasRouter,Route,Link}from'react-router-dom'//导入storeimport{Provider,connect}from'react-redux';importstore从'./redux/store.js'从'./logo.svg'导入徽标从'./components/plan.js'导入计划从'./components/home.js'导入主页从'./components/pupop.js'importTestRouterfrom'./components/testrouter.js'importDetailfrom'./components/detail.js'import'./App.css'import'./components/comment.css'importcreateHistory来自'history/createBrowserHistory'consthistory=createHistory()classAppextendsComponent{constructor(props){super(props);}render(){return(//store的挂载欢迎光临oReactPlan

  • 首页
  • 计划表
  • 二级路径由
  • );}}exportdefaultApp然后connectstoresrc/component/plant.jsimportReactinplan.js,{Component}from'react'import{connect}from'react-redux';importstorefrom'../redux/store.js';//importdefinedactionimport{show,deletePlan}from'../actions/plan.js';classPlanextendsComponent{constructor(props){super(props);}//showpopupshow(){letb=this.props.planlist.show;store.dispatch(show(!b));}//删除计划delete(id){store.dispatch(deletePlan(id));}//js重定向路由细节(id){this.props.history.push(`/detail/${id}`)}render(){return(

    计划列表

    添加计划

    标题操作{this.props.planlist.planlist.map((item,index)=>{return({item.title}删除)})})}}constmapStateToProps=function(存储){return{planlist:store.planlist};};//将商店连接为propsexportdefaultconnect(mapStateToProps)(Plan);同样,下面的js连接到src/component/detail.jsimportReact,{Component}from'react'import{connect}from'react-redux';importstorefrom'../redux/store.js';class细节扩展组件{constructor(props){super(props);//根据路由idFilterwithstoreletitem=props.planlist.planlist.filter((data)=>data.id==props.match.params.id)console.log(item)this.state={plan:item[0]}}render(){return(

    计划详情

    id:{this.state.plan.id}

    标题:{this.state.plan.title}

    内容:{this.state.plan.content}

    )}}constmapStateToProps=函数(存储){返回{计划列表:store.planlist};};//连接tore和组件导出默认值从'../redux/store.js'导入商店;从'../actions/plan.js'导入{show,addPlan};classPupopextendsComponent{constructor(props){super(props)this.state={id:'',title:'1',content:'1'}}//取消按钮操作close(){letb=this.props.planlist.show;this.setState({id:'',title:'',content:''})store.dispatch(show(!b));}//输入框架事件handleChage(str,e){this.setState({id:Math.ceil(Math.random()*10000),[str]:e.target.value})}//确认操作符合(){store.dispatch(addPlan(this.state));this.setState({id:'',title:'',content:''})this.close();}render(){让self=this;返回(X

    计划的标题

    计划内容

    取消Confirm)}}constmapStateToProps=function(store){return{planlist:store.planlist};};//连接存储和组件导出默认连接(mapStateToProps)(Pupop);完成的github地址