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 <TodoListUI 
				handleInputChange={this.handleInputChange}
				inputValue={this.state.inputValue}
				handleAddItem={this.handleAddItem}
				list={this.state.list}
				deleteItemClick={this.handleDeleteItem}
		
		/>
	}
	
	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 (
		<div style={{marginTop:'10px',marginLeft:'10px'}}>
			<div>
			  <Input onChange={this.props.handleInputChange} placeholder={this.props.inputValue} style={{width:'300px',marginLeft:'10px',marginTop:'10px'}} />
			  <Button onClick={this.props.handleAddItem} type="primary" style={{marginLeft:'10px',marginTop:'10px'}} >提交</Button>
			</div>
			<List style={{marginLeft:'10px',marginTop:'10px',width:'300px'}}
				  bordered
				  dataSource={this.props.list}
				  renderItem={(item,index) => (<List.Item onClick={(index) => this.props.handleDeleteItem(index)}>{item}</List.Item> )}
			/>
		</div>
		   );
	}
}

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 (
		<div style={{marginTop:'10px',marginLeft:'10px'}}>
			<div>
			  <Input onChange={props.handleInputChange} placeholder={props.inputValue} style={{width:'300px',marginLeft:'10px',marginTop:'10px'}} />
			  <Button onClick={props.handleAddItem} type="primary" style={{marginLeft:'10px',marginTop:'10px'}} >提交</Button>
			</div>
			<List style={{marginLeft:'10px',marginTop:'10px',width:'300px'}}
				  bordered
				  dataSource={props.list}
				  renderItem={(item,index) => (<List.Item onClick={ (index) => props.handleDeleteItem(index)}>{item}</List.Item> )}
			/>
		</div>
		);
}

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请求;
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值