1. redux是用来干什么的?
redux是一个状态管理工具,类似于vue中的vuex,专门用来解决组件之间数据传递的问题。
2. redux的安装与创建
项目终端里输入:npm install redux --save 新建一个redux文件夹,里面分别创建reducer.js和store.js文件。
3. 示例1
初始数据是原始数据类型。 reducer.js
const initState = 0;
export default function myReducer(prevState=initState,action){
const {type,payload} = action;
if(type=="add"){
return prevState + payload
}else if(type=="minus"){
return prevState - payload
}else{
return prevState
}
}
store.js
import {createStore} from "redux";
import myReducer from "./reducer";
const store = createStore(myReducer)
export default store
App.js
import React, { Component } from 'react'
import store from "./redux/store"
export default class App extends Component {
componentDidMount(){
store.subscribe(()=>{
this.setState({})
})
}
add=()=>{
store.dispatch({
type:"add",
payload:1
})
}
minus=()=>{
store.dispatch({
type:"minus",
payload:2
})
}
render() {
return (
<div>
<h1>{store.getState()}</h1>
<button onClick={this.add}>增加1</button>
<button onClick={this.minus}>减少2</button>
</div>
)
}
}
效果 点击增加1按钮,数字增加1;点击减少2按钮,数字减少2。
4. 示例2
初始数据是对象的形式。 reducer.js
const initState = {name:"小明", age:18, gender:"boy"}
export default function myReducer(prevState=initState,action){
const {type,payload}=action;
if(type=="changeName"){
return {...prevState,name:payload.name}
}else if(type=="changeAge"){
return {...prevState,age:payload.age}
}else if(type=="changeGender"){
return {...prevState,gender:payload.gender}
}else{
return prevState
}
}
store.js
import {createStore} from "redux";
import myReducer from "./reducer";
const store = createStore(myReducer)
export default store
App.js
import React, { Component } from 'react'
import store from "./redux/store"
export default class App extends Component {
changeName=()=>{
store.dispatch({
type:"changeName",
payload:{name:"韩梅梅"}
})
}
changeAge=()=>{
store.dispatch({
type:"changeAge",
payload:{age:"20"}
})
}
changeGender=()=>{
store.dispatch({
type:"changeGender",
payload:{gender:"girl"}
})
}
render() {
console.log(store.getState())
return (
<div>
<h1>名字是{store.getState().name},年龄是{store.getState().age},性别是{store.getState().gender}</h1>
<button onClick={this.changeName}>改名字</button>
<button onClick={this.changeAge}>改年龄</button>
<button onClick={this.changeGender}>改性别</button>
</div>
)
}
}
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import reportWebVitals from './reportWebVitals';
import store from "./redux/store"
ReactDOM.render(
<App/>,
document.getElementById('root')
);
store.subscribe(()=>{
ReactDOM.render(
<App/>,
document.getElementById('root')
);
})
reportWebVitals();
效果 点击按钮,可以修改原始对象中对应的数据
5. actionCreator
创建creators.js文件 在App.js中引入actionCreator
6. 异步action
creator.js文件 异步action需要使用同步action函数作为返回值,处理函数形式的action需要引入第三方插件,中间件redux-thunk。 安装:npm install redux-thunk 需要在store.js文件中,调用中间件 效果 点击“改年龄”按钮,触发异步action,3秒后,年龄由18改为100。
7. react-redux
在react-redux中,把所有组件分为两大类,一类是UI组件,另一类是容器组件。UI组件由用户提供,容器组件由react-redux生成。
UI组件
- 只负责渲染页面,不处理逻辑
- 没有状态
- 所有的动态数据都由属性提供
- 不使用任何redux的api
容器组件
- 专门负责管理数据和业务逻辑,不负责UI界面
- 有状态(属性)
- 使用redux的api
react-redux安装:npm install react-redux
示例 creator.js reducer.js store.js App.js index.js 效果
8. 多组件数据共享
效果 页面中的按钮,都存在于About组件中。点击“更改”按钮,能够更改About组件中的数据;点击“更改Home数据”按钮,能够更改Home组件中的数据。 About组件:components/about/index.jsx
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {aboutAction} from "../../redux/actions/about"
import {homeAction} from "../../redux/actions/home"
class Index extends Component {
change=()=>{
this.props.aboutAction("about数据改了")
}
changeHome=()=>{
this.props.homeAction("home数据改了")
}
render() {
const {aboutRes:{aboutReducer:{name,msg}}} = this.props
return (
<div>
<h1>我是About组件--名字是{name}--{msg}</h1>
<button onClick={this.change}>更改</button>
<button onClick={this.changeHome}>更改Home数据</button>
</div>
)
}
}
export default connect(
state=>({aboutRes:state}),
{
aboutAction,
homeAction
}
)(Index)
Home组件:components/home/index.jsx
import React, { Component } from 'react'
import {connect} from 'react-redux'
import {homeAction} from "../../redux/actions/home"
class Index extends Component {
render() {
const {homeRes:{homeReducer:{name,msg}}} = this.props
return (
<div>
<h1>我是Home组件--名字是{name}--{msg}</h1>
</div>
)
}
}
export default connect(
state=>({homeRes:state}),
{
homeAction
}
)(Index)
|