React-Redux进阶

1、UI组件和容器组件

  • UI组件负责页面UI渲染,只关注页面渲染

  • 容器组件负责页面逻辑处理,只关注业务逻辑

  • 通过把一个组件的页面渲染代码和逻辑处理拆分成父子组件,各司其职,更清晰,更明了

  • 需要注意的是:
    子组件调用父组件方法函数时,还会遇到this指向问题。
    因为需要获取index的值,UI组件里用箭头函数来代替父组件bind(this)。

    code demo 详细可参考本人上一篇博客:React-Redux入门文章

  • TodoList.js

import React,{Component} from 'react';
import store from './store';
import {getAddItemAction,deleteItemAction,getChangeItemAction } from './store/actionCreator';
import TodoListUI  from './TodoListUI';

class TodoList extends Component {
	
	constructor(props) {
	    super(props);
		this.state = store.getState();
		store.subscribe(this.handleStoreChange);
	}
	
	render(){
		return 
	}
	
	handleInputChange = (e) => {
		const action = getChangeItemAction(e.target.value);
		store.dispatch(action);
	}
	
	handleAddItem = () => {
		const action = getAddItemAction();
		store.dispatch(action);
	}
	
	handleDeleteItem = (index) => {
		const action = deleteItemAction(index);
		store.dispatch(action);
	} 
	
	handleStoreChange = () => {
		this.setState(store.getState());
	}
}

export default TodoList;
  • TodoListUI .js
import React,{Component} from 'react';
import { Input,Button,List } from 'antd';
import 'antd/dist/antd.css';


class TodoListUI extends Component {
	
	render(){
	return (
		
( this.props.handleDeleteItem(index)}>{item} )} />
); } } export default TodoListUI;

2、无状态组件

  • 无状态组件就是一个函数。当一个普通的组件只有render函数的时候,可以用无状态组件替换普通组件,以提升性能。
    code demo 问题删除时:存在props不是一个函数异常,后面处理。
import React from 'react';
import { Input,Button,List } from 'antd';
import 'antd/dist/antd.css';

const TodoListUI = (props) => {
	return (
		
( props.handleDeleteItem(index)}>{item} )} />
); } export default TodoListUI;

3、使用Redux-thunk中间件实现异步请求

  • 当不使用中间件thunk的时候,action必须是一个对象,当使用thunk后action可以是对象、函数,这样我们就可以在对象中做异步操作等。实际上store只能接受一个对象,不过 store发现action 传过来的是函数的时候,会自动执行这个action函数.
    在这个函数里我们会再次定义一个action,并派发此action,此时的action为对象。这个时候store识别出了此对象则进行接收从而改变原始状态。
  • 好处:可以把复杂的异步数据处理从组件的生命周期里摘除出来,避免组件过于庞大,方便后期维护、测试。
  • https://github.com/zalmoxisus/redux-devtools-extension
  • https://github.com/reduxjs/redux-thunk
    code demo
  1. 安装redux-thunk中间件 npm install redux-thunk
  2. store里高级设置引入中间件,参考官方说明,核心代码如下
import {createStore,applyMiddleware,compose} from 'redux';
import reducer from './reducer';
import thunk from 'redux-thunk';

const composeEnhancers =
  typeof window === 'object' &&
	window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?   
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
    }) : compose;

const enhancer = composeEnhancers(
  applyMiddleware(thunk),
);

const store = createStore(reducer, enhancer);

export default store;

3) TodoList.js store可以支持函数,异步改造为

	componentDidMount() {
		const action = getTodoList();
		store.dispatch(action);
	}

4)actionCreator.js

export const initListAction = (data) => ({
	type: INIT_LIST_ACTION,
	data
});

export const getTodoList = () => {
	return (dispatch) => {
		axios.get('/list.json').then((res) => {
			const data = res.data;
			const action = initListAction(data);
			dispatch(action);
		})
	}
};

4、Redux-saga中间件的使用

  • https://github.com/redux-saga/redux-saga
  • 安装 npm install --save redux-saga 或 yarn add redux-saga
  • 与thunk的异同
    redu-thunk解决异步代码的问题。把异步代码都放到了action,利于自动化测试,以及代码的拆分管理。
    redux-saga同样是作异步代码拆分的中间件,可以使用redux-saga完全代替redux-thunk。
    引入redux-saga的区别:默认不引入store.dispatch(action); 会在reducer里通过if(action.type === Init_List){}来监听action的执行。引入redux-sage:saga.js的todoSage也可以接收 store.dispatch(action) dispath请求;

你可能感兴趣的:(前端工程师)