Redux:不是react,更多的用在react里面,管理react应用中多个组件共享
Redux工作流程:
什么情况需要redux:
- 总体原则: 能不用就不用, 如果不用比较吃力才考虑使用
-
某个组件的状态,需要共享
-
某个状态需要在任何地方都可以拿到
-
一个组件需要改变全局状态
-
一个组件需要改变另一个组件的状态
未拆分成redux的app.jsx
import React,{Component} from 'react'
export default class App extends Component{
state = {
number:0
}
Add = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
let number = this.state.number;
this.setState({number:number+count});
}
Der = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
let number = this.state.number;
this.setState({number:number-count});
}
Odd = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
let number = this.state.number;
if(number%2 === 1){
this.setState({number:number+count});
}
}
Ancy = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
let number = this.state.number;
setTimeout(()=>{
this.setState({number:number+count});
},1000);
}
render(){
return(
<div>
<p>Click {this.state.number} times</p>
<div>
<select name="" id="" ref={select => this.select = select}>
{/* 这里用的非可控组件获取value,我的理解是将select放到this中,之后再用this.来取,来做到相同组件内的交互
但是不同于this.state.****,这个是放到state中,但是非可控组件不需要。也不同于父组件向子组件传值用props
于是目前为止有了三种传值方式:
1.this.***
2.this.state.***
3.this.props.***
*/}
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<button onClick={this.Add}>+</button>
<button onClick={this.Der}>-</button>
<button onClick={this.Odd}>奇数</button>
<button onClick={this.Ancy}>异步</button>
</div>
)
}
}
运行截图:
Redux版本:
Store对象
- 编码
import {createStore} from ‘redux’
import counter from ‘./reducers/counter’
const store = createStore(counter) - 作用:redux库的核心的管理对象
- 它内部维护着:state、reducer
- 核心方法:
getState()
dispatch(action)
subscribe(listener) - 编码
store.getState()
store.dispatch({type:‘INCREMENT’, number})
store.subscribe(render)
redux的核心概念
8.3.1. action
- 标识要执行行为的对象
- 包含2个方面的属性
a. type: 标识属性, 值为字符串, 唯一, 必要属性
b. xxx: 数据属性, 值类型任意, 可选属性 - 例子:
const action = {
type: ‘INCREMENT’,
data: 2
} - Action Creator(创建Action的工厂函数)
const increment = (number) => ({type: ‘INCREMENT’, data: number})
8.3.2. reducer - 根据老的state和action, 产生新的state的纯函数
- 样例
export default function counter(state = 0, action) {
switch (action.type) {
case ‘INCREMENT’:
return state + action.data
case ‘DECREMENT’:
return state - action.data
default:
return state
}
} - 注意
a. 返回一个新的状态
b. 不要修改原来的状态
8.3.3. store - 将state,action与reducer联系在一起的对象
- 如何得到此对象?
import {createStore} from ‘redux’
import reducer from ‘./reducers’
const store = createStore(reducer) - 此对象的功能?
getState(): 得到state
dispatch(action): 分发action, 触发reducer调用, 产生新的state
subscribe(listener): 注册监听, 当产生了新的state时, 自动调用
第一步:生成 store对象
第二步:创建reducers对象,每一个reducers就是一个函数
第三步,关联reducers和store
第四步,修改app.jsx,store里面有getState()方法用来取默认值、dispatch()方法用来修改值。
- 传入store到app.jsx
- 修改app.jsx里面的方法
- 最后发布更新
源码:
index.js
import React from 'react'
import ReactDOM from 'react-dom'
import App from './components/app'
import {createStore} from 'redux'
import {counter} from './redux/reducers'
//生成一个store对象,在createStore()里面关联reducers里面的函数
const store = createStore(counter);// 内部会第一次调用reducer函数得到初始的state=0,
//等于零是因为在reducers里面已经赋予了state形参默认值
console.log(store);
function render(){
ReactDOM.render(<App store={store}></App> , document.getElementById('root'));
}
//初始化渲染
render();
//订阅监听
store.subscribe(render);
reducers.jsx:
/*
这是一个包含n个reducer的模块
注:一个模块只有一个default
*/
import {INCREMENT,DECREMENT} from './action-type'
export function counter(state=0,action){//形参默认值
// console.log(state+""+action);
switch(action.type){
case INCREMENT:
return state + action.data;
case DECREMENT:
return state - action.data;
default:
return state;
}
}
app.jsx:
import React,{Component} from 'react'
import {INCREMENT,DECREMENT} from '../redux/action-type'
export default class App extends Component{
Add = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
//调用store的方法来更新状态,用dispatch()
this.props.store.dispatch({type:INCREMENT,data:count});
}
Der = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
// let number = this.state.number;
// this.setState({number:number-count});
this.props.store.dispatch({type:DECREMENT,data:count});
}
Odd = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
// let number = this.state.number;
let number = this.props.store.getState();
if(number%2 === 1){
this.props.store.dispatch({type:INCREMENT,data:count});
}
}
Ancy = () =>{
// console.log(this.select.value);
let count = this.select.value*1;
let number = this.state.number;
setTimeout(()=>{
this.props.store.dispatch({type:INCREMENT,data:count});
},1000);
}
render(){
//得到store里面的默认值
// console.log(this.props.store.getState());
const count = this.props.store.getState();
console.log(count);
return(
<div>
<p>Click {count} times</p>
<div>
<select name="" id="" ref={select => this.select = select}>
{/* 这里用的非可控组件获取value,我的理解是将select放到this中,之后再用this.来取,来做到相同组件内的交互
但是不同于this.state.****,这个是放到state中,但是非可控组件不需要。也不同于父组件向子组件传值用props
于是目前为止有了三种传值方式:
1.this.***
2.this.state.***
3.this.props.***
*/}
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
</select>
</div>
<button onClick={this.Add}>+</button>
<button onClick={this.Der}>-</button>
<button onClick={this.Odd}>奇数</button>
<button onClick={this.Ancy}>异步</button>
</div>
)
}
}
action-type.jsx:
/*
包含所有action type的常量字符串
*/
export const INCREMENT = 'INCREMENT';
export const DECREMENT = 'DECREMENT';
来源:CSDN
作者:Lion Of WU
链接:https://blog.csdn.net/NDSoumig/article/details/103792503