React-Redux入门

2021-03-22 11:49:52 浏览数 (1)

1、概念
  • react只是一个轻量级的视图层框架,如果要做大型应用就要搭配视图层框架redux一起使用
  • redux组件之间的传值非常简单,redux里面要求我们把数据都放在一个公共的存储区域store里面,组件之中尽量少放数据,也就是所有数据都不放在组件自身了,都把它放到一个公用的存储空间里面,然后组件改变数据就不需要传递了,改变store里面的数据之后其它的组件会感知到里面的数据发生改变。这样的话不管组件的层次有多深,但是走的流程都是一样的,会把数据的传递简化很多。
2、Redux的工作流程
3、使用Ant Design实现TodoList页面布局

ant design https://ant.design/docs/react/introduce-cn

  • yarn add antd
  • demo如下:
代码语言:javascript复制
import React,{Component} from 'react';
import { Input,Button,List } from 'antd';
import 'antd/dist/antd.css';

const data = [
  'Racing car sprays burning fuel into crowd.',
  'Japanese princess to wed commoner.',
  'Australian walks 100km after outback crash.',
  'Man charged over missing wedding girl.',
  'Los Angeles battles huge wildfires.',
];


class TodoList extends Component {
	
	render(){
		return (<div>
					  <Input placeholder="Basic usage" style={
  {width:'300px',marginLeft:'10px',marginTop:'10px'}} />
					  <Button type="primary" style={
  {marginLeft:'10px',marginTop:'10px'}} >Primary</Button>,
					  <List style={
  {marginLeft:'10px',marginTop:'10px',width:'300px'}}
						  bordered
						  dataSource={data}
						  renderItem={item => (
							<List.Item>
								{item}
							</List.Item>
					  )}
					/>
		       </div>
			   );
	}
}

export default TodoList;
4、创建store
  • yarn add redux
  • demo code
代码语言:javascript复制
import {createStore} from 'redux';
import reducer from './reducer';

const store = createStore(reducer);

export default store;
代码语言:javascript复制
const defaultState = {
	inputValue: '123',
	list: [1,2]
}

export default (state=defaultState, action)=>{
	return state;
}
代码语言:javascript复制
import React,{Component} from 'react';
import { Input,Button,List } from 'antd';
import store from './store/';
import 'antd/dist/antd.css';

class TodoList extends Component {
	
	constructor(props) {
	    super(props);
		this.state = store.getState();
		console.log(this.state);
	}
	
	render(){
		const {inputValue,list} = this.state;
		return (<div>
					  <Input placeholder={inputValue} style={
  {width:'300px',marginLeft:'10px',marginTop:'10px'}} />
					  <Button type="primary" style={
  {marginLeft:'10px',marginTop:'10px'}} >Primary</Button>,
					  <List style={
  {marginLeft:'10px',marginTop:'10px',width:'300px'}}
						  bordered
						  dataSource={list}
						  renderItem={item => (
							<List.Item>
								{item}
							</List.Item>
					  )}
					/>
		       </div>
			   );
	}
}

export default TodoList;
5、Action和Reducer的编写,TodoList增删

谷歌访问助手——https://github.com/haotian-wang/google-access-helper 1)要想更新state中的数据,首先派发一个action,action通过dispatch方法传给store。 2)store把之前的数据previousState和传过来的action转发给reducers函数。 3)reducers接收state和action后进行数据处理,重新生成一个newState(原state只读不改),把newState作为返回值返回给store。 4)store接收newState,将新数据替换原来的数据。 5)react组件中观测到数据发生改变(store.subscribe),会从store里面重新取数据(state),更新组件的内容,页面发生变化。

actionTypes 拆分管理,统一管理,方便排错 使用actionCreator统一创建action

  • index.js
代码语言:javascript复制
import {createStore} from 'redux';
import reducer from './reducer';

const store = createStore(
	reducer,
	// redux-devtools工具调试
	window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);

export default store;
  • reducer.js
代码语言:javascript复制
import {CHANGE_INPUT_TYPE,ADD_LIST_ITEM,DELETE_LIST_ITEM} from './actionTypes';

const defaultState = {
	inputValue: '',
	list: []
}

export default (state=defaultState, action)=>{
	// console.log(state,action);
	if(action.type === CHANGE_INPUT_TYPE){
		// 深拷贝,reducer不允许直接修改state
		const newState = JSON.parse(JSON.stringify(state));
		newState.inputValue = action.value;
		return newState;
	}
	if(action.type === ADD_LIST_ITEM){
		const newState = JSON.parse(JSON.stringify(state));
		newState.list.push(newState.inputValue);
		newState.inputValue = '';
		return newState;
	}
	if(action.type === DELETE_LIST_ITEM){
		const newState = JSON.parse(JSON.stringify(state));
		newState.list.splice(newState.index,1);
		return newState;
	}
	return state;
}
  • TodoList .js
代码语言:javascript复制
import React,{Component} from 'react';
import { Input,Button,List } from 'antd';
import store from './store';
import {getAddItemAction,deleteItemAction,getChangeItemAction } from './store/actionCreator';
import 'antd/dist/antd.css';

class TodoList extends Component {
	
	constructor(props) {
	    super(props);
		this.state = store.getState();
		console.log(this.state);
		store.subscribe(this.handleStoreChange);
	}
	
	render(){
		const {inputValue,list} = this.state;
		return (<div>
					  <Input onChange={this.handleInputChange} placeholder={inputValue} style={
  {width:'300px',marginLeft:'10px',marginTop:'10px'}} />
					  <Button onClick={this.handleAddItem} type="primary" style={
  {marginLeft:'10px',marginTop:'10px'}} >提交</Button>
					  <List style={
  {marginLeft:'10px',marginTop:'10px',width:'300px'}}
						  bordered
						  dataSource={list}
						  renderItem={(item,index) => (<List.Item onClick={this.deleteItemClick.bind(this,index)}>{item}</List.Item> )}
					/>
		       </div>
			   );
	}
	
	handleInputChange = (e) => {
		// console.log(e.target.value);
		const action = getChangeItemAction(e.target.value);
		store.dispatch(action);
	}
	
	handleAddItem = () => {
		const action = getAddItemAction();
		store.dispatch(action);
	}
	
	deleteItemClick(index) {
		const action = deleteItemAction(index);
		store.dispatch(action);
	} 
	
	handleStoreChange = () => {
		// console.log('handleStoreChange');
		this.setState(store.getState());
	}
}

export default TodoList;
  • actionTypes.js
代码语言:javascript复制
export const CHANGE_INPUT_TYPE ='change_input_type';
export const ADD_LIST_ITEM = 'add_list_item';
export const DELETE_LIST_ITEM = 'delete_list_item';
  • actionCreator.js
代码语言:javascript复制
import {ADD_LIST_ITEM ,DELETE_LIST_ITEM,CHANGE_INPUT_TYPE } from './actionTypes';

export const getChangeItemAction = (value) => ({
	type: CHANGE_INPUT_TYPE,
	value
});

export const getAddItemAction = () => ({
	type: ADD_LIST_ITEM,
});

export const deleteItemAction = (index) => ({
	type: DELETE_LIST_ITEM,
	index
});
6、redux知识点
  • redux三个基本原则: ①:store必须是唯一的 ②:只有store可以改变自己的内容 ③:reducer 必须是纯函数
  • 只有store能改变自己内容说明在reducer里我们不能直接操作state,只能通过定义新变量copy state的值, 然后对新变量进行操作并 return 出新变量,不允许直接改变state。
  • 什么是纯函数? 给固定的输入,就一定会有固定的输出,并且不会有任何副作用。 所以对于异步函数(定时器、ajax数据请求等)、动态时间都不适意在reducer里订阅。
  • store核心api: crerteStore(): 创建一个store store.dispatch(action): 派发action,传递store store.getState(): 获取store的所有数据 store.subscribe(): 订阅store的变化,接收的回调函数在store改变时候就会自动执行

本文由来源 jackaroo2020,由 javajgs_com 整理编辑,其版权均为 jackaroo2020 所有,文章内容系作者个人观点,不代表 Java架构师必看 对观点赞同或支持。如需转载,请注明文章来源。

0 人点赞