react-redux笔记

目录

目录

redux理解图

搭建环境

react-redux代码编写

创建reducer操作并存储全局state -reducer(state,action){return 新state}

store.js 引入reducer集中管理全局state

入口文件index.js  挂载store,让所有组件共享全局state

App组件挂载UI组件 

UI组件可以:①显示state,②发送action修改state

 


Redux是专门用于做状态管理的js库,一般与react配合使用,集中管理多个组件共享的状态。

文档:

https://redux.js.org/

https://www.redux.org.cn/

https://github.com/reactjs/redux

 

案例页面效果:

案例文件结构:

redux理解图

 

搭建环境

第一种:react脚手架

npm install -g create-react-app

create-react-app myapp

npm run start

第二种:用webpack配置

npm init -y

npm i babel-loader babel/core @babel/preset-env @babel/preset-react  webpack webpack-cli webpack-dev-server -D

npm i react react-dom redux react-redux redux-thunk redux-devtools-extension -S

react项目文件夹结构

node_modules
dist
    -main.js		默认出口文件
public				相当于url的根路径
    -favicon.cio
    -index.html		在浏览器中打开该文件访问整个项目
src
    -App.js
    -index.js		默认入口文件
    -index.css		通用css
package.json
webapck.config,js

创建webpack.config.js文件

module.exports = {
	mode:'development',			
    module: {
		rules: [
			{
				test: /\.js|jsx$/,
				exclude: /(node_modules|bower_components)/ ,
				use: {
					loader: 'babel-loader',
					options: {
				  		presets: ['@babel/env','@babel/react']
					}
				}
			}
		]
	},
	devtool:'inline-source-map',
	watch : true 
}

在package.json中写dev和build命令:

npm run dev运行时构建,借助webpack-dev-server工具:不打包项目,实时监测代码,模拟生产环境的效果

npm run build是webpack打包命令:自动构建src/main.js文件,到dist/all.js文件中

  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "npx webpack serve",
    "build":"webpack"
  },

public/index.html中引入webpack-dev-server默认在内存中隐式生成的main.js文件


<body>
    <div id="app-container"></div> 
    <!-- webpack-dev-server 默认在内存中隐式生成一个main.js-->
    <!-- npm run dev 后访问localhost:8080-->
    <script src="/main.js"></script>
    <!-- npm run build 后右键在浏览器打开此文件-->
    <!-- <script src="../dist/main.js"></script> -->
</body>

想要项目打包后模拟生产环境:可在cmd中用serve命令

npm i serve -g

将index.html放在dist文件夹下,然后在dist文件夹下cmd命令 输入 serve,就能在localhost:5000打开index.html

<body>
    <div id="app-container"></div> 
    <script src="./main.js"></script>
</body>

react-redux代码编写

创建reducer操作并存储全局state -reducer(state,action){return 新state}

根据action改变state,返回新的state

constant.js用于定义action对象中type类型的常量值,目的:便于管理的同时防止程序员单词写错

reducers/compo1.js根据actions/compo1.js 操作并存储组件Compo1对应的state

export const ADD1 = 'add1'
export const REDUCE1 = 'reduce1'
export const ADD2 = 'add2'
export const REDUCE2 = 'reduce2'
<--reducers/compo1.js文件-->
import {ADD1, REDUCE1} from "../constant"
const initState = {v1: 0} //初始化状态
export default function countReducer(preState = initState, action) {
  const {type, data} = action
  switch (type) {
    case ADD1:
      return {...preState, v1: preState.v1 + data}
    case REDUCE1:
      return {...preState, v1: preState.v1 - data}
    default:
      return preState
  }
}

<--actions/compo1.js文件-->
import {ADD1, REDUCE1} from "../constant"
//同步action,就是指action的值为Object类型的一般对象
export const add1 = (data) => ({type: ADD1, data})
export const reduce1 = (data) => ({type: REDUCE1, data})

//异步action,就是指action的值为函数,异步action中一般都会调用同步action
export const add1Async = (data, time) => {
  return (dispatch) => {
    setTimeout(() => {
      dispatch(add1(data))
    }, time)
  }
}

reducers/compo2.js根据actions/compo2.js 操作并存储组件Compo2对应的state

<--reducers/compo2.js-->
import {ADD2, REDUCE2} from "../constant"
const initState = {v2: 0} //初始化状态
export default function countReducer(preState = initState, action) {
  const {type, data} = action
  switch (type) {
    case ADD2:
      return {...preState, v2: preState.v2 + data}
    case REDUCE2:
      return {...preState, v2: preState.v2 - data}
    default:
      return preState
  }
}

<--actions/compo2.js 专门为Compo2组件生成action对象-->
import {ADD2, REDUCE2} from "../constant";
//同步action,值为Object类型
export const add2 = (data) => ({type: ADD2, data});
export const reduce2 = (data) => ({type: REDUCE2, data});

//异步action,值为函数,一般都会调用同步action。
export const add2Async = (data, time) => {
  return (dispatch) => {
    setTimeout(() => {
      dispatch(add2(data));
    }, time);
  };
};

reducers/index.js汇总reducer

import { combineReducers } from 'redux'
// 引入reducer
import compo1 from './compo1'
import compo2 from './compo2'

//汇总所有的reducer
export default  combineReducers({
	compo1,
	compo2
})

 

store.js 引入reducer集中管理全局state

import {createStore, applyMiddleware} from "redux"
//引入redux-thunk,用于支持异步action
import thunk from "redux-thunk"
//引入redux-devtools-extension
import {composeWithDevTools} from "redux-devtools-extension"
//汇总后的reducer
import reducer from "./reducers"

export default createStore(reducer, composeWithDevTools(applyMiddleware(thunk)))

入口文件index.js  挂载store,让所有组件共享全局state

import React from "react"
import ReactDOM from "react-dom"
import App from "./App"
import store from "./redux/store"
import {Provider} from "react-redux"
console.log(store)
ReactDOM.render(
  //Provider要求是最大的组件,通过属性将store往下传
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById("app-container")
)

App组件挂载UI组件 

import React from "react";
import { PropTypes } from "prop-types";
import "./App.css"
import Compo1 from "./component/Compo1";  
import Compo2 from "./component/Compo2";  
class App extends React.Component{
    render() {
	    return (
            <div className="app">App组件
                <Compo1 />
                <Compo2 />
            </div>
        )
	}
}
export default App;

UI组件可以:①显示state,②发送action修改state

Compo1/index.js

import React from "react"
//链接UI组件和redux
import {connect} from "react-redux"
//引入组件1的actions,操作组件1维护的全局state
import {add1, reduce1, add1Async} from "../../redux/actions/compo1"
class Compo1 extends React.Component {
  render() {
    return (
      <div>
        <h2>Compo1组件,v1:{this.props.v1},v2:{this.props.v2}</h2>
        <button onClick={() => this.props.add1(2)}>操作v1,+2</button>
        <button onClick={() => this.props.reduce1(2)}>操作v1,-2</button>
        <button onClick={() => this.props.add1Async(2, 1000)}>
          操作v1,异步+2
        </button>
      </div>
    )
  }
}
// state数据
const mapStateToProps = (state) => ({
  v1: state.compo1.v1,
  v2: state.compo2.v2,
})
// actions方法
const mapDispatchToProps = {add1, reduce1, add1Async}
//接收全局state需要connect一下。一般map生成的组件不需要connect,因为不需要看见全局state
// connet()函数中两个参数函数返回的json中的k会自动成为props中的对象
// 组件中就可以通过this.props访问state数据和使用action方法了
export default connect(mapStateToProps, mapDispatchToProps)(Compo1)

Compo2/index.js

import React from "react"
//链接UI组件和redux
import {connect} from "react-redux"
//引入actions,操作全局state
import {add2, reduce2} from "../../redux/actions/compo2"
class Compo2 extends React.Component {
  render() {
    console.log(this.props)
    return (
      <div>
        <h2>Compo2组件,v1:{this.props.v1},v2:{this.props.v2}</h2>
        <button onClick={() => this.props.add2(2)}>操作v2,+2</button>
        <button onClick={() => this.props.reduce2(2)}>操作v2,-2</button>
      </div>
    )
  }
}
const mapStateToProps = (state) => ({
  v1: state.compo1.v1,
  v2: state.compo2.v2,
})
const mapDispatchToProps = {add2, reduce2}
export default connect(mapStateToProps, mapDispatchToProps)(Compo2)

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值