简单理解
- 目录
index.js
// 相当于图书馆管理员 就是store库
import {createStore} from "redux"
import state from './reducer.js'
// createStore 创建store 库
const store = createStore(
state,
window.__REDUX_DEVTOOLS_EXTENSION_ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
export default store
reducer.js
// 相当于图书馆管理软件 index管理员会来找我
const defaultStore = {
inputValue:"请输入内容",
list:[
"aa评论51",
"aa评论2",
"aa评论3"
]
}
//把已知的数据暴露出去
export default (state = defaultStore,action) => {
//reducer只能接受state 不能改变state
if (action.type == "inputChange") {
//深拷贝
let newState = JSON.parse(JSON.stringify(state))
//拷贝后更新
newState.inputValue = action.event
//跟新后返回
return newState
}
return state;
}
app.js
import React from 'react'
import {render} from 'react-dom'
import { InputItem , Button ,WhiteSpace,List} from 'antd-mobile';
import 'antd-mobile/dist/antd-mobile.css';
import "./App.css"
import store from "./store/index"
let app = class App extends React.Component {
constructor (props) {
super(props)
this.inputChange = this.inputChange.bind(this)
this.storeChange = this.storeChange.bind(this)
this.showClick = this.showClick.bind(this)
this.click = this.click.bind(this)
//将store库给state !!!!!!!!!!!!!!!!!!!!!
this.state = store.getState()
//进行订阅 更新试图 !!!!!!!!!!!!!!!!!!!!!!!!
store.subscribe(this.storeChange)
}
//进行订阅 更新试图
inputChange(event){
const action = {type:'inputChange', event}
store.dispatch(action)
}
//进行订阅 更新试图
storeChange() {
this.setState(store.getState())
console.log("storeChange",store.getState())
}
click() {
const data = this.state.inputValue;
store.dispatch({type:"click",data})
console.log(this.state)
}
showClick(){
console.log("当前状态-》",store.getState())
console.log("当前state-》",this.state)
}
MyDelete(e,index){
store.dispatch({type:"delete",index})
console.log(e,index)
}
render() {
return (
<div>
<hr/>
<h1>重新学习redux</h1>
<hr/>
<div className="box" >
<InputItem onChange={this.inputChange} clear placeholder="请输入内容" ></InputItem> <WhiteSpace />
<Button onClick={this.click} type="primary">添加</Button><WhiteSpace />
<ul>
{
this.state.list.map(function (itme,index) {
return <li key={index}>{itme} <span onClick={(e) => {this.MyDelete(e,index)}}>删除</span></li>
}.bind(this))
}
</ul>
</div>
<span onClick={this.showClick} >查看当前状态信息</span>
</div>
)
}
}
export default app
项目化
- 最终实现功能跟什么一样
目录结构
index.js 不变
新增action-type 管理所有type值
export const CLICK = "click"
export const DELETE = "delete"
export const INPUTCHANGE = "inputChange"
新增actions 管理多个action
import {CLICK , DELETE , INPUTCHANGE } from './action-type.js'
export const action_inputChange = (event) => ({
type:INPUTCHANGE,
event
})
export const action_click = (data) => ({
type:CLICK,
data
})
export const action_MyDelete = (index) => ({
type:DELETE,
index
})
reducre.js
// 相当于图书馆管理软件 index管理员会来找我
import {CLICK , DELETE , INPUTCHANGE } from './action-type.js'
const defaultStore = {
inputValue:"请输入内容",
list:[
"aa评论51",
"aa评论2",
"aa评论3"
]
}
function comments(state = defaultStore, action) {
switch (action.type) {
case INPUTCHANGE:
state.inputValue = action.event
return state
case CLICK:
state.inputValue = "请输入内容"
state.list.unshift(action.data)
return state
console.log(action.data)
case DELETE:
state.list.splice(action.index,1)
return state
default:
return state
}
}
//把已知的数据暴露出去
export default comments
再app.js 中使用
- 先引入 actions
import {action_inputChange,action_click,action_MyDelete} from './store/actions.js';
- 然后使用其方法
inputChange(event){
const action = action_inputChange(event)
store.dispatch(action)
}
click() {
const data = this.state.inputValue;
store.dispatch(action_click(data))
}
MyDelete(e,index){
store.dispatch(action_MyDelete(index))
console.log(e,index)
}
redux-devtools调试工具
store/index.js
const store = createStore(
reducer, /* preloadedState, */
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
Axios
npm install --save axios
- 简单使用使用
import axios from 'axios'
componentDidMount(){
axios.get("https://easy-mock.com/mock/5d98513c8c63954ea11dd25c/hopeReact/data1")
.then((res)=>{
const action = action_getData(res.data.data)
store.dispatch(action)
})
}
Redux-thunk中间件
npm install --save redux-thunk
修改store 下的 index.js
// 相当于图书馆管理员 就是store库
import {createStore , applyMiddleware, compose} from "redux"
import state from './reducer.js'
import thunk from 'redux-thunk'
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
const enhancer = composeEnhancers(applyMiddleware(thunk))
// createStore 创建store 库
const store = createStore(state,enhancer);
export default store
redux调试工具就可以正常使用了
基本使用
Redux-thunk
既可以返回对象也可以返回一个函数
优化上面的异步请求 在中间件中发送请求
App.js
- 原本
componentDidMount(){
axios.get("https://easy-mock.com/mock/5d98513c8c63954ea11dd25c/hopeReact/data1")
.then((res)=>{
const action = action_getData(res.data.data)
store.dispatch(action)
})
}
- 修改(引入
action_getDateLists
)
componentDidMount(){
store.dispatch(action_getDateLists())
}
action.js 中 添加
action_getDateLists
export const action_getDateLists = () => {
return (dispatch) => {
axios.get("https://easy-mock.com/mock/5d98513c8c63954ea11dd25c/hopeReact/data1")
.then((res)=>{
const action = action_getData(res.data.data)
dispatch(action)
console.log(res.data.data)
})
}
}
/*
action creator模块
*/
import {ADD, REDUCE} from './action-types.js'
export const add = number => ({type: ADD, number})
export const reduce = number => ({type: REDUCE, number})
// 异步action creator(返回一个函数)
export const incrementAsync = number => {
return dispatch => {
setTimeout(() => {
// 调用add
dispatch(add(number))
}, 1000)
}
}
redux-saga中间件
npm install --save redux-saga
基本使用
store 下的 index.js
// 相当于图书馆管理员 就是store库
import {createStore , applyMiddleware, compose} from "redux"
import state from './reducer.js'
// import thunk from 'redux-thunk'
import creactSagaMiddleware from 'redux-saga' //<-------引入
import mySages from './sagas' //<-------新建sagas.js
const sagaMiddleware = creactSagaMiddleware();
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}) : compose
const enhancer = composeEnhancers(applyMiddleware(sagaMiddleware)) //<-------
// createStore 创建store 库
const store = createStore(state,enhancer);
sagaMiddleware.run(mySages) //<-------配置完成
export default store
新建sagas.js
function* mySaga() {
}
export default mySaga
开始使用
actions.js
export const action_getData = (data) => ({
type:GETDATA,
data
})
export const action_getMyLists = () => ({
type:GET_MY_LIST
})
action-type.js
export const GETDATA = "getData"
export const GET_MY_LIST = "getMyList"
sagas.js
import { takeEvery , put} from 'redux-saga/effects'
import { GET_MY_LIST } from './action-type'
import {action_getData} from './actions'
import axios from 'axios'
function* mySaga() { //类型为GET_MY_LIST就调用getList()
yield takeEvery(GET_MY_LIST,getList)
}
function* getList(){
const res = yield axios.get("https://easy-mock.com/mock/5d98513c8c63954ea11dd25c/hopeReact/data1")
const action = action_getData(res.data.data)
yield put(action)
}
export default mySaga
reducer.js
// 相当于图书馆管理软件 index管理员会来找我
import {CLICK , DELETE , INPUTCHANGE ,GETDATA} from './action-type.js'
const defaultStore = {
inputValue:"请输入内容",
list:[
]
}
function comments(state = defaultStore, action) {
switch (action.type) {
case INPUTCHANGE:
state.inputValue = action.event
return state
case CLICK:
state.inputValue = "请输入内容...."
state.list.unshift(action.data)
return state
console.log(action.data)
case DELETE:
state.list.splice(action.index,1)
return state
case GETDATA:
state.list = action.data
default:
return state
}
}
// function comments(state = defaultStore, action) {
// let newState = JSON.parse(JSON.stringify(state))
// //拷贝后更新
// switch (action.type) {
// case INPUTCHANGE:
// newState.inputValue = action.event
// return newState
// case CLICK:
// newState.inputValue = "请输入内容"
// newState.list.unshift(action.data)
// return newState
// console.log(action.data)
// case DELETE:
// newState.list.splice(action.index,1)
// return newState
// default:
// return state
// }
// }
//把已知的数据暴露出去
export default comments
react-redux插件
专门用来简化react应用中使用redux
npm install --save react-redux
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from "react-redux" //<-----引入"提供器"
import store from './store/index' //<-----引入store 状态
import App from './App';
ReactDOM.render((
// 提供器
// 定义渲染根组件标签的函数
<Provider store={store}>
<App />
</Provider>
), document.getElementById('root'));
app.js 组件
import React,{Component} from 'react'
import './App.css'
// import store from "./store/index.js" //<-------不在需要 状态直接通过this.props来获取
import { connect } from "react-redux" //<-----引入连接器
import { action_onChange } from "./store/action"
class App extends Component{
constructor(props){
super(props);
{/* 相当于vue 中的data*/}
// this.state = store.getState() //<-------不在需要 状态直接通过this.props来获取
}
render() {
return (
<div>
<h1>重新学习redux</h1>
<input
type="text"
placeholder={ this.props.placeholder } //<--------使用状态直接 this.props.placeholder
value={ this.props.inputValue } //<--------使用方法this.props.inputValue
onChange={ this.props.change}
/><button type="button">添加</button>
<ul>
<li>11111 <a href="#">删除</a></li>
<li>11111 <a href="#">删除</a></li>
<li>11111 <a href="#">删除</a></li>
</ul>
</div>
)
}
}
// 映射状态
const stateToProps = (state) => {
return {
placeholder:state.placeholder,
inputValue:state.inputValue
}
}
// 映射方法 使用的时候 this.props.change
const dispatchToProps = (dispatch) => {
return {
change(e){
console.log(e.target.value,"组件value")
let action = action_onChange(e.target.value)
dispatch(action)
}
}
}
//状态 //方法
export default connect(stateToProps,dispatchToProps)(App);
这样在app.js 中获取状态直接通过this.props来获取 不需要
将store库给state
this.state = store.getState()
代码优化
此时组件是不需要状态了可以使用函数的方式来创建
方法通过解构赋值从props中获取 使用的时候从 props.placeholder 简化到 placeholder
import React,{Component} from 'react'
import './App.css'
// import store from "./store/index.js" //<-------不在需要 状态直接通过this.props来获取
import { connect } from "react-redux" //<-----引入连接器
import { action_onChange,action_onClick,action_myDelete } from "./store/action"
//--->---->---->--优化区域开始>-->-->--->---->---->>>>-->>>->----->--->------
function App(props){
//解构赋值 把方法直接从props拿出来
let { placeholder,inputValue,change,click,myDelete} = props
return (
<div>
<h1>重新学习redux</h1>
<div className="box">
<input
type="text"
placeholder={placeholder }
value={inputValue }
onChange={change}
/><span onClick={click.bind(inputValue)}>添加</span>
</div>
<ul>
{
props.list.map(function(itme,index){
return <li key={index}>{itme} <a onClick={ (e) => {myDelete(e,index) } }>删除</a></li>
})
}
</ul>
</div>
)
}
//--->---->---->--优化区域结束>-->-->--->---->---->>>>-->>>->----->--->------
// 映射状态
const stateToProps = (state) => {
return {
placeholder:state.placeholder,
inputValue:state.inputValue,
list:state.list
}
}
// 映射方法 使用的时候 this.props.change
const dispatchToProps = (dispatch) => {
return {
change(e){
let action = action_onChange(e.target.value)
dispatch(action)
},
click(v,inputValue){
let action = action_onClick()
dispatch(action)
},
myDelete(e,index){
let action = action_myDelete(index)
dispatch(action)
}
}
}
//状态 //方法
export default connect(stateToProps,dispatchToProps)(App);