react-redux及异步插件 redux-thunk&redux-saga使用

react-redux使用

1.安装 npm install --save react-redux
2.index.js中,通过Provider 设置store

const App = (
	<Provider store={store}>
	<TodoList/>
	</Provider>
);

3.组件中通过 connect 关联store,u获取store中的state,对store进行dispatch
//把store中的state映射成组件的props,组件中通过props拿数据

import React from "react";
import store from './store/index';
//引入antd组件Input,Button
import {
	Input,
	Button,
	List
} from 'antd';
//引入antd css样式
import 'antd/dist/antd.css';
import {
	connect
} from 'react-redux';
import {
	getInputChangeAction,
	getAddItemAction,
	getDelItemAction
} from './store/actionCreator';

//无状态组件,只有render的组件可以改成无状态组件,不用执行生命周期函数,只是返回模板,提升性能
const TodoList = (props) => {
	//结构赋值简化代码
	const {
		inputValue,
		list,
		changeInputValue,
		handleBtnClick,
		handleItemDelete
	} = props;
	return (
		<div>
			<div style={{marginTop:'10px'}}>
               <Input  placeholder="todo list"
               value={inputValue}
			   onChange={changeInputValue}
               style={{width:'300px',marginRight:'10px'}} />
               <Button type="primary"
               onClick={handleBtnClick}
               >提交</Button>
            </div>
              <List style={{width:'300px',marginTop:'10px'}}
			      bordered
			      dataSource={list}
			      renderItem={(item,index) => (<List.Item onClick={()=>(handleItemDelete(index))}>{item}</List.Item>)}
			    />
        </div>
	);
};
const mapStateToProps = (state) => {
	return {
		inputValue: state.inputValue,
		list: state.list
	};
}

//把store.dispatch挂载到组件的props
const mapDispatchToProps = (dispatch) => {
	return {
		changeInputValue(e) {
			const action = getInputChangeAction(e.target.value);
			dispatch(action);
		},
		handleBtnClick() {
			const action = getAddItemAction();
			store.dispatch(action);

		},
		handleItemDelete(index) {
			const action = getDelItemAction();
			store.dispatch(action);
		}
	};
}
//组件通过connect与store关联,store中的state发生变化时,自动更新,不需要再store.subsrible订阅
export default connect(mapStateToProps, mapDispatchToProps)(TodoList);

4.组件中只有render函数,优化成无状态组件

redux-thunk
//redux-thunk使用
//1.npm install --save redux-thunk
//2.store index.js 中引入

import {
	createStore,
	applyMiddleware
} from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';

const store = createStore(reducer, applyMiddleware(thunk));

export default store;

//3.actionCreator中定义action,返回函数

import {
	INPUT_CHANGE_VALUE,
	ADD_LIST_ITEM,
	DEL_LIST_ITEM,
	INIT_TODO_LIST
} from './actionTypes';

export const getInputChangeAction = (value) => ({
	type: INPUT_CHANGE_VALUE,
	value
});
export const getAddItemAction = (value) => ({
	type: ADD_LIST_ITEM
});
export const getDelItemAction = (index) => ({
	type: DEL_LIST_ITEM,
	index
});

export const initTodoListAction = (list) => ({
	type: INIT_TODO_LIST,
	list
});
export const initTodoListByThunk = () => {
	return (dispatch) => {
		var data = ['1111', '3333', '5555']
		// axios.get('/list.json').then((res) => {
		const action = initTodoListAction(data);
		dispatch(action);
		// })
	}
}

// 函数做异步调用处理,返回的结果后,调用action去更新store
//4.组件中调用 异步处理action

import React, {
	Component
} from "react";
import store from '../store-thunk/index';
import TodoListUI2 from './TodoListUI2';
import {
	getInputChangeAction,
	getAddItemAction,
	getDelItemAction,
	initTodoListByThunk
} from '../store-thunk/actionCreator';
class TodoListUseUI extends Component {
	constructor(props) {
		super(props);
		// 从store中获取数据
		this.state = store.getState();
		this.handleInputChange = this.handleInputChange.bind(this);
		this.handleBtnClick = this.handleBtnClick.bind(this);
		this.handleItemDelete = this.handleItemDelete.bind(this);
		this.handleStoreChange = this.handleStoreChange.bind(this);
		//订阅store,store发生变化时,执行handleStoreChange来更新state
		store.subscribe(this.handleStoreChange);
	}
	render() {
		return (
			<TodoListUI2
			inputValue={this.state.inputValue}
			list={this.state.list}
			handleInputChange={this.handleInputChange}
			handleBtnClick={this.handleBtnClick}
			handleItemDelete={this.handleItemDelete}
			></TodoListUI2>
		);
	}
	componentDidMount() {
		const action = initTodoListByThunk();
		store.dispatch(action);
	}
	handleStoreChange() {
		this.setState(store.getState());
	}
	handleInputChange(e) {
		const action = getInputChangeAction(e.target.value);
		store.dispatch(action);
	}
	handleBtnClick() {
		const action = getAddItemAction();
		store.dispatch(action);

	}
	handleItemDelete(index) {
		const action = getDelItemAction();
		store.dispatch(action);
	}
}
export default TodoListUseUI;

redux-saga
// saga使用:
// 1.安装 npm install redux-saga --save
// 2.在store index.js中引入saga

import {
	createStore,
	applyMiddleware
} from 'redux';
import reducer from './reducer';
import mySaga from './sagas'
import createSagaMiddleware from 'redux-saga'
// create the saga middleware
const sagaMiddleware = createSagaMiddleware()
// mount it on the Store
const store = createStore(
	reducer,
	applyMiddleware(sagaMiddleware)
)

// then run the saga
sagaMiddleware.run(mySaga)

export default store;

// 3.编写sagas.js
sagas.js

import {
	put,
	takeEvery
} from 'redux-saga/effects'
import axios from "axios";
import {
	GET_INIT_LIST
} from './actionTypes';
import {
	initTodoListAction
} from './actionCreator';


function* getInitList() {
	try {
		const res = yield axios.get('/list.json');
		const action = initTodoListAction(res.data);
		yield put(action);
	} catch (e) {
		console.log("请求失败");
		const data = ['222', '4444']
		const action = initTodoListAction(data);
		yield put(action);
	}
}

function* mySaga() {
	yield takeEvery(GET_INIT_LIST, getInitList); //拦截 type:GET_INIT_LIST的action,进行处理
}

export default mySaga;

// 4.组件中发生action getInitListAction()

import React, {
	Component
} from "react";
import store from '../store-saga/index';
import TodoListUI2 from './TodoListUI2';
import {
	getInputChangeAction,
	getAddItemAction,
	getDelItemAction,
	getInitListAction
} from '../store-saga/actionCreator';
class TodoListUseUI extends Component {
	constructor(props) {
		super(props);
		// 从store中获取数据
		this.state = store.getState();
		this.handleInputChange = this.handleInputChange.bind(this);
		this.handleBtnClick = this.handleBtnClick.bind(this);
		this.handleItemDelete = this.handleItemDelete.bind(this);
		this.handleStoreChange = this.handleStoreChange.bind(this);
		//订阅store,store发生变化时,执行handleStoreChange来更新state
		store.subscribe(this.handleStoreChange);
	}
	render() {
		return (
			<TodoListUI2
			inputValue={this.state.inputValue}
			list={this.state.list}
			handleInputChange={this.handleInputChange}
			handleBtnClick={this.handleBtnClick}
			handleItemDelete={this.handleItemDelete}
			></TodoListUI2>
		);
	}
	componentDidMount() {
		const action = getInitListAction(); //会被saga拦截,进行异步请求处理,初始化list
		store.dispatch(action);
	}
	handleStoreChange() {
		this.setState(store.getState());
	}
	handleInputChange(e) {
		const action = getInputChangeAction(e.target.value);
		store.dispatch(action);
	}
	handleBtnClick() {
		const action = getAddItemAction();
		store.dispatch(action);

	}
	handleItemDelete(index) {
		const action = getDelItemAction();
		store.dispatch(action);
	}
}
export default TodoListUseUI;

// 5.sagas.js中拦截GET_INIT_LIST action,进行异步请求逻辑处理,
// 将返回的结果 同发送action initTodoListAction 去更新store
//
// saga使用比thunk要复杂一些,但提供很多api(put,takeEvery等),比较适合在大型项目应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值