react中redux+react-redux插件的应用

首先下载安装   redux   react-redux

npm install redux --save-dev

npm install react-redux --save-dev

 

 

 

1、先创建一个store的一个文件夹(这个是一个公共的仓库)

  并在store的文件夹中创建一个store.js文件、一个actions文件夹(这个是所要执行的动作指令)、reducer文件夹(这个是一个纯函数)

  

 

 

 

2、在store文件夹下的store.js文件中写入如下代码:

import {createStore,applyMiddleware} from "redux";
import reducer from "./reducer/reducer.js";    //这个是所导入的纯函数
import thunk from 'redux-thunk'        //这个是用于异步请求的中间件
const store=createStore(reducer,applyMiddleware(thunk));
export default store;

 

3、在store文件夹下的actions文件夹下的action.js文件中写入如下代码:

import axios from "axios";
export default {
  handlePutback(){
    return {
      type:"PUTBACK",    //这个是所发送的指令
    }
  },
  handleGetCinemaDetail(id){
    return (dispatch)=>{        //用dispatch这个函数执行这个异步
      var url_cinemaDetail="/v3/ajax/cinemaDetail?cinemaId="+id
      axios.get(url_cinemaDetail).then((res)=>{
        dispatch({
          type:"GETCINEMADETAIL",    //这个是所发送的指令
          res                //这个是axios发送请求所请求回来的数据
        })
      })
    }
  }
}

 

 

4、在store文件夹下的reducer文件夹下的reducer.js文件中写入如下代码:(这个是封装的总的reducer纯函数)

import {combineReducers} from "redux";
import filmReducer from "./Film/filmReducer.js";     //这个子的纯函数
import cinemaReducer from "./Cinema/cinemaReducer.js";  //这个子的纯函数
import myReducer from "./My/myReducer.js";    //这个子的纯函数
import detailspageReducer from "./Detailspage/detailspageReducer.js";      //这个子的纯函数
const reducer=combineReducers({
  film:filmReducer,
  cinema:cinemaReducer,
  my:myReducer,
  detailspage:detailspageReducer,
})
export default reducer;

 

 

5、在子的reducer中,代码如下:

var initState = {    //这个是用于初始化数据
  list: [],
  coming: [],
  Times: [],
  cinemas: localStorage.cinemas ? JSON.parse(localStorage.cinemas).cinemas : [],
  brand: {},
  district: {},
  hallType: {},
  service: {},
  subway: {},
  timeRanges: {},
  cine:{},
  cinemaTitle: localStorage.cinemaTitle ? JSON.parse(localStorage.cinemaTitle) : {},
  detailMovie:localStorage.detailMovie?JSON.parse(localStorage.detailMovie):{},
}
const reducer = (state = initState, actions) => {
  var newState = { ...state }    //用于拷贝初始化数据
  if (actions.type === "DATA") {      //匹配相对应的action,之后进行相对性的操作
    newState.list = actions.list;
  }
  if (actions.type === "DISPLAY") {
    newState.brand = actions.brand;
    localStorage.brand=JSON.stringify(newState.brand);
    newState.district = actions.district;
    localStorage.district=JSON.stringify(newState.district);
    newState.hallType = actions.hallType;
    localStorage.hallType=JSON.stringify(newState.hallType);
    newState.service = actions.service;
    localStorage.service=JSON.stringify(newState.service);
    newState.subway = actions.subway;
    localStorage.subway=JSON.stringify(newState.subway);
    newState.timeRanges = actions.timeRanges;
    localStorage.timeRanges=JSON.stringify(newState.timeRanges);
  }
  return newState
}
export default reducer;

 

6、之后再你所要用的主页面引入你所创建的store,代码如下:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "./flexble.js"
import './index.css';
import store from "./store/store.js"    //引入你所创建的store
import {Provider} from "react-redux"    //通过react-redux中的Provider   来连接store
ReactDOM.render(
  <Provider store={store}>       //之后通过标签进行包裹  并传入store
    <App />
  </Provider>
  , document.getElementById('root')
);

 

 

这个一个react的仓库就创建完毕啦!!!

 

 

 

 

7、在组建中运用store中的公共数据和函数方法,代码如下:

import React, { Component } from 'react';
import styled from 'styled-components'    //用于react的样式格力的插件
import action from "../../../store/reducer/Film/action"
import { connect } from "react-redux"    //react-redux中的高阶组件
import Swiper from "swiper"
import 'swiper/dist/css/swiper.css'

class Show extends Component {
  componentDidMount() {
    this.props.handleData();
    this.props.handleTime();
  }
  componentDidUpdate() {
    new Swiper('.swiper-container', {
      freeMode: true,
      slidesPerView: 3,
      // autoplay:true,
      // loop:true,
    });
  }
  render() {
    return (
      <Div>
          {/*轮播导航 */}
          <div className="show-lately">
            <p className="show-title">近期最受期待</p>
            <div className="swiper-container" >
            <div className="show swiper-wrapper">
            {
              this.props.com ? this.props.com.map((item, index) => {
              return <div className="swiper-slide" key={index}>
                <div className="show-content">
                  <div className="show-poster"><img src={item.img.slice(5,22)+148+"."+208+item.img.slice(25)} /><span>{item.wish}人想看</span></div>
                  <h5>{item.nm}</h5>
                  <p>{item.comingTitle}</p>
                </div>
               </div>
              }) : ""
            }
          </div>
        </div>
      </Div >
    );
  }
}
 
 
//通过映射的方式将store中的数据和方法映射到组件中
var mapState = (state) => {    //通过映射的方式将store中的数据映射到组件中
  console.log(state.film.Times)
  return {
    com: state.film.coming.coming,
    time: state.film.Times
  }
}
var mapActions = (dispatch) => {    //通过映射的方式将store中的方法映射到组件中
  return {
    handleData() {
      dispatch(action.getDatas())
    },
    handleTime() {
      dispatch(action.getTimes())
    }
  }
}
export default connect(mapState, mapActions)(Show);    //react-redux中的高阶组件




const Div = styled.div`      //样式的修改------------------类似less一样(注意  需要定义  之后用``这个进行定义)
background:#f5f5f5;
height:100%;
width:100%;
position:absolute;
top:1.86rem;
//轮播导航样式
.show-lately{
padding: .2rem 0 .2rem .3rem;
background-color: #fff;
margin-bottom: .1rem;
overflow:hidden;
.show-title{
margin: 0 0 .2rem;
font-size: .3rem;
color: #333;
}
.swiper-container{
// display:initial;
.swiper-wrapper{
// overflow: scroll;
white-space: nowrap;
// display: initial;
.swiper-slide{
display: inherit;
width:auto;
.show-content{
display: inline-block;
// width: 2rem;
overflow: hidden;
margin-right: .1rem;
.show-poster{
width: 2rem;
height: 2.7rem;
position: relative;
margin-bottom: .1rem;
img{
width:100%;
height:100%;
}
span{
display: inline-block;
position: absolute;
left: .1rem;
bottom: .02rem;
color: #faaf00;
font-size: .2rem;
font-weight: 600
}
}
h5{
margin: 0 0 .03rem;
font-size: .26rem;
color: #222;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
width:70%;
}
p{
margin: 0;
font-size: .24rem;
color: #999;
}
}
}
 
}
}
 
}
.show-list{
background:#fff;
.show-list-title{
padding: .2rem 0 0 .2rem;
font-size: .3rem;
color: #333;
}
.show-list-box{
display:flex;
align-items: center;
.list-img{
width: 1.4rem;
height:100%
margin-left:.2rem;
img{
width: 1.4rem;
height: 100%;
display: block;
}
}
.list-cont{
justify-content:space-between;
display:flex;
width: 70%;
border-bottom: 1px solid #e6e6e6;
padding: .2rem 0 .2rem .1rem;
.list-cont-l{
padding:.1rem .2rem;
width:70%;
.list-left-t{
margin-bottom: .07rem;
display:flex;
align-items: center;
span:nth-of-type(1){
width:60%;
font-size:.4rem;
color: #333;
font-weight: 700;
padding-right:.1rem;
flex-shrink: 1;
display:inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
span:nth-of-type(2){
border:1px solid #3c9fe6;
width: 1.1rem;
height: .35rem;
border-radius: .1rem;
background: #f4f4f4;
color: #3c9fe6;
}
}
.list-left-b{
color:#666;
font-size:.32rem;
div:nth-of-type(1){
span{
font-weight: 700;
color: #faaf00;
font-size: .34rem;
margin-left:.1rem;
}
}
div:nth-of-type(2){
width:90%;
margin-top:.1rem;
span{
display: inline-block;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 100%;
}
}
div:nth-of-type(3){
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 90%;
}
}
}
.list-cont-r{
width:20%;
position: relative;
right:.4rem;
span{
position:absolute;
top: 0;
bottom: 0;
margin: auto;
left: 0;
display: inline-table;
// background:#3c9fe6;
background:red;
width: 1.1rem;
height: .6rem;
line-height:.6rem;
text-align:center;
border-radius: .1rem;
color: #fff;
cursor: pointer;
}
}
}
}
}
}
`

 

 

 

 

react-redux的工作流程如下,用于更好的理解

 

 

 

Redux 三大原则

    • 单一数据源 整个应用的 state 被存储在一个 Object tree 中,且只存在于唯一的Store中。

    • state 是只读的 唯一改变 state 的方法就是触发 action,action 是一个用于描述发生事件的普通对象,视图部分只需要表达想要修改的意图,所有修改都会被集中化处理。

    • 使用纯函数来执行修改 为了实现根据 action 修改 state值,我们就需要编写 Reducer。它是一个纯函数,接收先前的 state 和 action 返回新的 state ,随着应用的变大,你可以将它拆成多个小的 Reducer ,分别独立操作 state tree 中的不同部分。

 

 

 

2.具体工作步骤

 

 

 

 

Action

const add =()=>{
	return {
		type:"add",
		data:id,
	}
}

上边函数返回的就是一个 Action,它是一个包含 type 和 data 的对象。 Action 的作用就是告诉状态管理器需要做什么样的操作,正如上边的例子,就是要添加一条信息,这样就定义了一个Action,而 data 就是你做这个操作需要的数据。

Reducer

reducer 是一个函数(纯函数),接受 旧 state 和 action,根据不同的 Action 做出不同的操作并返回新的 state 。即:(state, action) => state

const reducer = (state,action)=>{
	switch(action.type){
		case "add":
			state['newItemId'] = action.data;
			return {...state};
		case "delete":
			delete state.newItemId;
			return {...state};
		default :
			return state;
	}
}

在没有任何操作的情况下,我们返回的 state 与原 state 相同。

Store

import { createStore } from 'redux';
const store = createStore(reducer);

这就是 store, 用来管理 state 的单一对象,其中有三个方法:

  • store.getState():获取state ,如上,经过 reducer 返回了一个新的 state,可以用该函数获取。

  • store.dispatch(action):发出 action,用于触发 reducer 更新 state,

  • store.subscribe(listener):监听变化,当 state 发生变化时,就可以在这个函数的回调中监听。

React-Redux

Redux 官方提供的 React 绑定库。

容器组件与傻瓜组件

在应用中,通常容器组件对于 Redux 可知,他们的子组件应该是"傻瓜的"(傻瓜组件),并且通过porps获取数据。 容器组件: 通过组件 state 属性维护自身及其子组件的数据,它可以向 Redux 发起 action ,从 Redux 获取 新state值。 傻瓜组件: 通过 props 调用回调函数,从 props 获取数据展示。

注入 Store

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore } from 'redux';
import { Provide } from 'react-redux';
import reducer from './reducer';
import App from './app';

const store = createStore(reducer);
class RootComp extends React.Component{
	render(){
		//...
		return (//将整个视图结构包进 Provider
			<Provider store={store}>
				<App/>
			</Provider>
		)
	}
}
ReactDOM.render(<RootComp/> ,document.getElementById('root'));

connect#

该方法用于从 UI 组件生成容器组件,

import React from 'react';
import { connect } from 'react-redux';
import Home from './home';

class AppContainer extends React.Component{
	render(
		return (
			<Home/>
		);
	)
}
const App = connect()(AppContainer);//这里的App就是生成的容器组件。
export default App;

connect( mapStateToProps , mapDispatchToProps , mergeProps , options )();

连接 React 组件与 Redux Store

  • mapStateToProps 该参数为一个 function mapStateToProps (state,[ownProps]){...},定义该参数后组件就可以监听 Redux Store 的变化,任何时候只要store发生变化,该函数就会被调用,该函数必须返回一个纯对象,它会与组件的 props 结合,而第二个参数 ownProps 被指定时,它代表传递到该组件的props,且只要组件收到新的 props ,mapStateToProps 就被调用。

  • mapDispatchToProps 通常我们会将该参数省略,此时默认情况下,dispatch 会注入到组件的props中,在你需要出发 action 的地方(可能是某个事件函数)使用该disaptch 函数将 action 发出。

例子:

在上边例子中,我们只要点击下添加链接,组件就会通过点击事件触发 dispath 函数 发送 action 到 store 中的 reducer, reducer 则根据 action 的 type 来决定执行什么操作,之后在 store 中新增一条记录(newItemId)后返回一个新的 state (里边包含Store中发生改变后的所有值),由于组件使用 connect 将自己与 Store 绑定起来,Store 中的值发生变化就会执行 mapStateToProps,将新的 state 放入组件的 props,从而引发组件的渲染。

posted @ 2019-10-09 10:30  程序员-壯  阅读(628)  评论(0编辑  收藏  举报