1.redux的使用
1.State (是只读的)
用于存取数据
!注意不能直接修改
2.action
用于修改 state
Action 是把数据从应用(译者注:这里之所以不叫 view 是因为这些数据有可能是服务器响应,用户输入或其它非 view 的数据 )传到 store 的有效载荷。它是 store 数据的唯一来源。一般来说你会通过 store.dispatch() 将 action 传到 store
3.reducer
为了描述 action 如何改变 state tree
Reducer 只是一些纯函数,它接收先前的 state 和 action,并返回新的 state。刚开始你可以只有一个 reducer,随着应用变大,你可以把它拆成多个小的 reducers,分别独立地操作 state tree 的不同部分,因为 reducer 只是函数,你可以控制它们被调用的顺序,传入附加数据,甚至编写可复用的 reducer 来处理一些通用任务,如分页器。
4.store
- 提供 getState() 方法获取 state;
- 提供 dispatch(action) 方法更新 state;
- 通过 subscribe(listener) 注册监听器;
- 通过 subscribe(listener) 返回的函数注销监听器。
下载已创建项目 npm i redux -s
//在src目录下创建一个store
//新建一个index.js 初始化 store
import {createStore} from 'redux'
import reducer from './reducer.js'
const store=createStore(reducer)
export default store;
//新建一个 action.js 文件 用于修改state数据
const sendAction = (type,value) => {// 这里可以写参数,也可以直接写死
return { type, value };
};
export default sendAction;
//例如
const sendAction = () => {
return { type:"send_type", value:"我是action数据" };
};
//reducer.js 用于管理action 的一个函数
const nameInitialState = {
value:"默认值"
}
const reducer= (state = nameInitialState, action) => {
console.log('reducer',state,action);
switch (action.type) {
case "send_type":
return Object.assign({},state,action)
default:
return state
}
}
export default reducer;
// 如果action 过多 可以拆分 引入combineReducers
import { combineReducers } from 'redux'
const nameInitialState = {
value:"默认值"
}
const about1 = (state = nameInitialState, action) => {
console.log('reducer',state,action);
switch (action.type) {
case "send_type":
return Object.assign({},state,action)
default:
return state
}
}
const about2 = (state = nameInitialState, action) => {
console.log('about2',state,action);
switch (action.type) {
case "send_type2":
return Object.assign({},state,action)
default:
return state
}
}
const reducer=combineReducers({about1,about2})
export default reducer;
在about1.js 文件下使用
//about.js 你在那个文件下使用就引入 store
import store from "../redux/index.js";
import sendAction from "../redux/action.js";
class about extends Component {
constructor(props) {
super(props);
}
handle = () => {
const action = sendAction("send_type", "我是about1");
store.dispatch(action);//发送action更新state
};
unsubscrib=null
componentDidMount() {
this.unsubscrib=store.subscribe(() => { //在挂着生命周期 开启监听,
console.log(store.getState());//获取store state 的信息
this.setState({});//刷新视图数据
});
}
componentWillUnmount() {//组件销毁 一定要销毁监听 避免内存溢出
console.log("我被销毁了");
this.unsubscrib()
}
render() {
return (
<div>
<button onClick={this.handle}>点我发送一个action</button>
{store.getState().value} //这是不拆分
{store.getState().about2.value}//这是拆分
</div>
);
}
}
2.react-redux的使用
在那个组件文件使用stroe中,都导入了store。然而在组件中直接导入Store是非常不利于组件复用的。一个应用中,最好只有一个地方需要直接导入Store,这个位置应该是在调用最顶层React组件的位置。
不让组件直接导入Store,那就只能让组件的上层组件把Store传递下来了。然而props存在缺陷,即所有的组件都要帮助传递这个props。React提供了一个叫Context的功能,能够完美地解决这个问题。
但是我们有一个react-redux的库完美解决自己手写context 功能问题
react-redux redux 两个都要下载
npm i react-redux redux
react-redux 有两个函数
一个是 Provider 用于传递store
一个是 connect 用于输出使用sotre组件的
connect有两个主要参数
接收数据参数 mapStateToProps
发送数据 mapDispatchToProps
//在app.js 引入 Provider store 文件
import React, { Component } from "react";
import store from "./redux/index.js"; //初始化文件 与上面文件结构一致
import { Provider } from "react-redux";
class element extends Component {
constructor(props) {
super(props);
}
render() {
return (
<Provider store={store}> //传递store
<div>
<ComA />
<ComB />
</div>
</Provider>
);
}
}
export default element;
comA 发送数据
import React, { Component } from 'react';
import {connect} from 'react-redux';
import {sendCombAction} from "../redux/action.js";//与上面action 文件结构一致 命名自己修改
console.log(sendCombAction);
class comA extends Component {
constructor(props) {
super(props)
}
handleClick=()=>{
console.log(this.props.sendAction()); //调用sendAction函数 发送数据
}
render() {
return (
<div>
<button onClick={this.handleClick}>+</button>
</div>
);
}
}
const mapDispatchToProps=(dispatch)=>{
return {
sendAction:()=>{ //返回一个sendAction函数
dispatch(sendCombAction("send_comb",1))
}
}
}
//第一个参数 接收数据 第二参数 发送数据
export default connect(null,mapDispatchToProps)(comA);
2comB(接收数据)
import React, { Component } from 'react';
import {connect} from 'react-redux';
class comB extends Component {
constructor(props) {
super(props)
}
render() {
console.log(this.props.comb.count);
return (
<div>
{this.props.comb.count}
</div>
);
}
}
const mapStateToProps=(state,ownProps)=>{
return state//一定要返回state 数据
}
export default connect( mapStateToProps)(comB);
// reducer.js 文件 加多一个
const count = {//默认值
count:0
}
const comb = (state = count, action) => {
console.log('comb',state,action);
switch (action.type) {
case "send_comb":
action.count+=state.count
return Object.assign({},state,action)
default:
return state
}
}