Redux基本语法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gao_xu_520/article/details/80512149

一.Redux

1.什么是Redux

Redux是专注于状态管理,单一状态 ,单向数据流处理.

在Redux中,所有的数据(比如state)被保存在一个被称为store的容器中 → 在一个应用程序中只能有一个。store本质上是一个状态树,保存了所有对象的状态。任何UI组件都可以直接从store访问特定对象的状态。要通过本地或远程组件更改状态,需要分发一个action。分发在这里意味着将可执行信息发送到store。当一个store接收到一个action,它将把这个action代理给相关的reducer。reducer是一个纯函数,它可以查看之前的状态,执行一个action并且返回一个新的状态。简单的理解:old state  ———》action(行为状态:type:{接受类型})  ——》reducer 函数(计算state,)——》得到 new  state

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

//3.新建store  compose结合redux devTool的插件
const store = createStore(chat,applyMiddleware(thunk))

//1.定义常量  action
const MSG_LIST = 'MSG_LIST' //聊天信息列表
const MSG_RECV = 'MSG_RECV' //接受信息
const MSG_READ = 'MSG_READ' //未读信息

/*2.reducer
函数有2个参数,一个state 一个action
*/
//state的值
const initState = {
	chatmsg:[],//每条聊天的信息
	users:{},//用户信息
	unread:0//未读信息列表
}

export function chat(state=initState, action){
	switch(action.type){
		case MSG_LIST:
			return {...state,users:action.payload.users,chatmsg:action.payload.msgs,unread:action.payload.msgs.filter(v=>!v.read&&v.to==action.payload.userid).length}
		case MSG_RECV:
			return {...state,chatmsg:[...state.chatmsg,action.payload],unread:state.unread+n}
		case MSG_READ:
			return {...state,chatmsg:[...state.chatmsg,action.payload]}
		default:
		 	return state
	}
}

//简单的话  就只要1-3的步骤,不过一般都是还含有action函数   

//1.2  action函数
function msgList(msgs,users,userid){
	return {type:MSG_LIST,payload:{msgs,users,userid}}
}
//1.1  接受请求的后端的函数
export function getMsgList(){
	return (dispatch)=>{
		axios.get('/user/getmsglist')
			.then(res=>{
				if (res.status===200&&res.data.code===0) {
					dispatch(msgList(res.data.msgs,res.data.users))
				}
			})		
	}
}

2.三个基本原则

A.单一数据源
       整个应用的 state 被储存在一棵 object tree 中,并且这个 object tree 只存在于唯一一个 store 中。
B.State 是只读的
唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。
C.使用纯函数来执行修改

为了描述 action 如何改变 state tree ,你需要编写 reducers。

二、基本概念

1.Store

Store 就是保存数据的地方,你可以把它看成一个容器。整个应用只能有一个 Store。

Redux 提供createStore这个函数,用来生成新的Store。

import { createStore } from 'redux';
const store = createStore(fn);

createStore函数接受另一个函数作为参数,返回新生成的 Store 对象

注意:

createStore方法还可以接受第二个参数,表示 State 的最初状态。这通常是服务器给出的。

let store = createStore(todoApp, window.STATE_FROM_SERVER)

上面代码中,window.STATE_FROM_SERVER就是整个应用的状态初始值。注意,如果提供了这个参数,它会覆盖 Reducer 函数的默认初始值。

2. State

state是Store对象包含所有数据。如果想得到某个时点的数据,就要对 Store 生成快照。这种时点的数据集合,就叫做 State。
当前时刻的 State,可以通过store.getState()拿到。

import { createStore } from 'redux';
const store = createStore(fn);
const state = store.getState();

Redux 规定, 一个 State 对应一个 View。只要 State 相同,View 就相同。你知道 State,就知道 View 是什么样,反之亦然。

3.Action

Action是把数据从应用传到store的有效载荷。它是store数据的唯一来源。一般来说,通过store.dispatch()将action传到store。

State 的变化,会导致 View 的变化。但是,用户接触不到 State,只能接触到 View。所以,State 的变化必须是 View 导致的。Action 就是 View 发出的通知,表示 State 应该要发生变化了。

Action 是一个对象。其中的type属性是必须的,表示 Action 的名称。

const ADD_TODO = 'ADD_TODO'
//Action 的名称是ADD_TODO,它携带的信息是字符串ADD_TODO

const action = {
	type: 'ADD_TODOS',
	payload: 'Learn Redux'
};
//Action 的名称是ADD_TODOS,它携带的信息是字符串Learn Redux。

可以这样理解,Action 描述当前发生的事情。改变 State 的唯一办法,就是使用 Action。它会运送数据到 Store。其他属性可以自由设置,社区有一个规范可以参考。

4.Action Creator

View 要发送多少种消息,就会有多少种 Action。如果都手写,会很麻烦。可以定义一个函数来生成 Action,这个函数就叫 Action Creator。简单来说Action 创建函数 就是生成 action 的方法。“action” 和 “action 创建函数” 这两个概念很容易混在一起,使用时最好注意区分。

在 Redux 中的 action 创建函数只是简单的返回一个 action:

function addTodo(text) {
  return {
    type: ADD_TODO,
    text
  }
}
const action = addTodo('Learn Redux');
上面代码中,addTodo函数就是一个 Action Creator。

5.Reducer

Store 收到 Action 以后,必须给出一个新的 State,这样 View 才会发生变化。这种 State 的计算过程就叫做 Reducer。

Reducer 是一个函数,它接受 Action 和当前 State 作为参数,返回一个新的 State。也可以这样说Reducers 指定了应用状态的变化如何响应 actions 并发送到 store 的,记住 actions 只是描述了有事情发生了这一事实,并没有描述应用如何更新 state。

//通过reducer函数来计算:根据老的state 和action ,生成新的state
const defaultState = 0;
const reducer = (state = defaultState, action) => {
  switch (action.type) {
    case 'ADD':
      return state + action.payload;
    default: 
      return state;
  }
};

const actions = [
	{ type: 'ADD', payload: 0 },
	{ type: 'ADD', payload: 1 },
	{ type: 'ADD', payload: 2 }
];
//1.新的store
const store=createStore(reducer);
//action 创建函数
function addTodo(payload) {
	return {
		type: 'ADD',
		payload
	}
}

//派发事件 传递action
store.dispatch(addTodo(2))
console.log(store.getState())//输出state的值是2

通过上面的代码,就可以了解到reducer函数就是计算state的过程。

注意:reducer有特别的一点就是纯函数。也就是说,只要是同样的输入,必定得到同样的输出。

纯函数是函数式编程的概念,必须遵守以下一些约束。

不得改写参数
不能调用系统 I/O 的API
不能调用Date.now()或者Math.random()等不纯的方法,因为每次会得到不一样的结果

由于 Reducer 是纯函数,就可以保证同样的State,必定得到同样的 View。但也正因为这一点,Reducer 函数里面不能改变 State,必须返回一个全新的对象.

请参考:Reducer 最佳实践,Redux 开发最重要的部分

Redux Reducer 的拆分

三.API

(一).Store API

1.store.getState()

store.getState()就是获取当前state的值

//派发事件 传递action
store.dispatch(addTodo(2))
console.log(store.getState())//输出state的值是2

2.store.dispatch()

store.dispatch()是 View 发出 Action 的唯一方法。store.dispatch接受一个 Action 对象作为参数,将它发送出去

function counter(state=0,action){
	switch(action.type){
		case '加机关枪':
			return state+1
		case '减机关枪':
			return state-1
		default:
			return 10
	}
}

//1.新的store
const store=createStore(counter);
//action 创建函数
function addTodo(text) {
  return {
    type: '加机关枪',
    text
  }
}

//派发事件 传递action
store.dispatch(addTodo('666'))
console.log(store.getState())//输出state的值是11

3.store.subscribe()

Store 允许使用store.subscribe方法设置监听函数,一旦 State 发生变化,就自动执行这个函数。

function counter(state=0,action){
	switch(action.type){
		case '加机关枪':
			return state+1
		case '减机关枪':
			return state-1
		default:
			return 10
	}
}
//1.新的store
const store=createStore(counter)

//通过store 获取状态
const init =store.getState();
console.log(init)
function Listener(){
	const current = store.getState();
	console.log(`现在有机枪${current}把`)
}
//随时监听state的变化
store.subscribe(Listener);


//派发事件 传递action
store.dispatch({type:'加机关枪'})

store.dispatch({type:'加机关枪'})

显然,只要把 View 的更新函数(对于 React 项目,就是组件的render方法或setState方法)放入listen,就会实现 View 的自动渲染。

store.subscribe方法返回一个函数,调用这个函数就可以解除监听。

let unsubscribe = store.subscribe(() =>
  console.log(store.getState())
);

unsubscribe();

4.replaceReducer(nextReducer)

替换 store 当前用来计算 state 的 reducer。这是一个高级 API。只有在你需要实现代码分隔,而且需要立即加载一些 reducer 的时候才可能会用到它。在实现 Redux 热加载机制的时候也可能会用到。 

四.Redux如何和React一起使用

例子:对机关枪的管理,这里上交(减少)和申请(增加机关枪)管理

Redux如何和React一起使用,具体操作:把store.dispatch方法传递给组件,内部可以调用修改状态,subscribe订阅render函数,每次修改都重新渲染,redux相关内容,一道单独的文件index.redux.js单端管理

1.首先创建action  对机关枪的操作  统一创建在index.redux.js

//6.通过发送过来的action 找到对应的type  就知道是 reducer 的counter函数时加1还是减1
//就得到新的store

//action
const ADD_GUN='加机关枪';
const REMOVE_GUN='减机关枪';

//reduer
export function counter(state=0,action){
	switch(action.type){
		case '加机关枪':
			return state+1
		case '减机关枪':
			return state-1
		default:
			return 10
	}
}

//action creator
export  function addGUN(){
	return {type:ADD_GUN}
}
export  function removeGUN(){
	return {type:REMOVE_GUN}
}

2.要引入模板 创建store   index.js

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import registerServiceWorker from './registerServiceWorker';
import { createStore } from 'redux'; 
import {counter,addGUN,removeGUN} from './index.redux';

//1.新建store
const store = createStore(counter);


function render() {
	//reactDOM 渲染页面
   //2.这个store 以在组件属性props传给Component 组件
	ReactDOM.render(<App store={store} addGUN={addGUN} removeGUN={removeGUN} />, document.getElementById('root'));
	registerServiceWorker();
}
render();
//3.以subscribe订阅render的函数 这样我们可以知道state的变化
store.subscribe(render);

Store 的监听函数设置为render,每次 State 的变化都会导致网页重新渲染。

3.组件页面的操作 App.js

import React from 'react';

class App extends React.Component {
	render() {
		//4.通过组件的属性props 获取store以及数据操作addGUN
		//5.在通过dispatch(addGUN()) 发送action
		const store=this.props.store;
		const num =store.getState();
		const addGUN=this.props.addGUN;
		const removeGUN=this.props.removeGUN;
		return (
			<div>
				<h1>现在有机枪{num}把</h1>
				<button onClick={()=>store.dispatch(addGUN())}>申请武器</button>
				<button onClick={()=>store.dispatch(removeGUN())}>上交武器</button>
			</div>
		);
	}
}

export default App;

参考:Redux 入门教程(一):基本用法

Redux.自述

通过上面的学习得到自己的理解:

创建action(多个类型)——》创建reducer(计算每个类型下的state的值)——》通过这个reducer函数  得到新的值state( const store=createStore(reducer) const state = store.getState();)——》把这个值以props属性传给组件——》组件接受新的值——》同时发布(dispatch)该组件的acton类型——》通过组件分派的action得到是reducer那种类型下的计算方法——》得到值

如果有理解错误,请大家指出来。

猜你喜欢

转载自blog.csdn.net/gao_xu_520/article/details/80512149