react-redux

在没有使用react-redux时

store实例有一个私有变量_state

state = store.getState()得到的是_state经过序列化在变成json对象,JSON.parse(JSON.stringify(this._state)); 

因此state和_state内容相同,但是修改state不会影响_state,事实上_state = reducer(state,action),

当执行store.dispatch(action)时,有两个步骤:第一,修改私有_state,_state = reducer(state,action),

第二,store.subscribe(fn)在监听_state的状态,只要store.dispatch(action)执行,不管_state是否发生变化,fn函数都会执行

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, bindActionCreators } from 'redux';
function reducer(state,action){
	if (typeof state === 'undefined') return {name:'Jack',num:0};
	switch (action.type){
		case "changeName":
		    return Object.assign({},state,action.payload);
		case "add":
		    return Object.assign({},state,{num: ++state.num});
		    default: return state;
	}
}
const store = createStore(reducer);
let actions = {
	changeName(name){
		return{
			type:'changeName',
			payload:{name:name}
		}
	},
	add(){
		return{
			type:'add'
		}
	}
}
actions = bindActionCreators(actions,store.dispatch)
class UI extends React.Component{
	render(){
		return(
			<div>
			  <p>{this.props.name}</p>
			  <p>{this.props.num}</p>
			  <input onChange = {event => this.props.changeName(event.target.value)} />
			  <button onClick = {event => this.props.add()}>add</button>
			</div>
		)
	}
}

function render(){
	let state = store.getState();
	ReactDOM.render(<UI changeName = {actions.changeName} add = {actions.add} name= {state.name} num = {state.num}/>,
	document.getElementById('test'))
}
store.subscribe(render);
render();

使用react-redux时

本质就是Object.assign(this.props,store.getState(),actions); store.subscribe(ReactDOM.render())

function getState(state){
return state;

}

参数state就是store.getState(),store是由<Provider store={store}><UI/></Provider>中的store提供的。

function getActions(){
return actions;

}

函数getActions()没有参数。

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, bindActionCreators } from 'redux';
import {connect,Provider} from 'react-redux';
function reducer(state,action){
	if (typeof state === 'undefined') return {name:'Jack',num:0};
	switch (action.type){
		case "changeName":
		    return Object.assign({},state,action.payload);
		case "add":
		    return Object.assign({},state,{num: 1+state.num});
		    default: return state;
	}
}
const store = createStore(reducer);
let actions = {
	changeName(name){
		return{
			type:'changeName',
			payload:{name:name}
		}
	},
	add(){
		return{
			type:'add'
		}
	}
}
actions = bindActionCreators(actions,store.dispatch)
class UI extends React.Component{
	render(){
		return(
			<div>
			  <p>{this.props.name}</p>
			  <p>{this.props.num}</p>
			  <input onChange = {event => this.props.changeName(event.target.value)} />
			  <button onClick = {event => this.props.add()}>add</button>
			</div>
		)
	}
}

function getState(state){
	return state;
}
function getActions(){
	return actions;
}
UI = connect(getState,getActions)(UI);
ReactDOM.render(<Provider store={store}><UI/></Provider>,
	document.getElementById('test'));

上面的代码可以将

actions = bindActionCreators(actions,store.dispatch);

function getActions(){return actions;}

这两条语句去掉

再将UI = connect(getState,getActions)(UI);修改成UI = connect(getState,actions)(UI);

因为当actions是json对象时,函数内部会自动调用bindActionCreators(actions,store.dispatch);


function getState(state,props){
return state;

}

当没有第二个参数props时,只会输出一次123

当有第二个参数props时,输出两次123

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, bindActionCreators } from 'redux';
import {connect,Provider} from 'react-redux';
function reducer(state,action){
	if (typeof state === 'undefined') return {name:'Jack',num:0};
	switch (action.type){
		case "changeName":
		    return Object.assign({},state,action.payload);
		case "add":
		    return Object.assign({},state,{num: 1+state.num});
		    default: return state;
	}
}
const store = createStore(reducer);
let actions = {
	changeName(name){
		return{
			type:'changeName',
			payload:{name:name}
		}
	},
	add(){
		return{
			type:'add'
		}
	}
}
class UI extends React.Component{
	render(){
		return(
			<div>
			  <p>{this.props.name}</p>
			  <p>{this.props.num}</p>
			  <input onChange = {event => this.props.changeName(event.target.value)} />
			  <button onClick = {event => this.props.add()}>add</button>
			</div>
		)
	}
}

function getState(state,props){
	console.log(123);
	return state;
}
UI = connect(getState,actions)(UI);
function render(name){
	ReactDOM.render(<Provider store={store}><UI name={name}/></Provider>,
	document.getElementById('test'));
}
render('Jack');
setTimeout(function(){
	render('Mike')
},3000)

也可以将映射分开:

import React from 'react';
import ReactDOM from 'react-dom';
import { createStore, bindActionCreators } from 'redux';
import {connect,Provider} from 'react-redux';
function reducer(state,action){
	if (typeof state === 'undefined') return {name:'Jack',num:0};
	switch (action.type){
		case "changeName":
		    return Object.assign({},state,action.payload);
		case "add":
		    return Object.assign({},state,{num: 1+state.num});
		    default: return state;
	}
}
const store = createStore(reducer);
let actions = {
	changeName(name){
		return{
			type:'changeName',
			payload:{name:name}
		}
	},
	add(){
		return{
			type:'add'
		}
	}
}
class OPT extends React.Component{
	render(){
		return(
			<div>
			  <input onChange = {event => this.props.changeName(event.target.value)} />
			  <button onClick = {event => this.props.add()}>add</button>
			</div>
		)
	}
}
OPT = connect(null,actions)(OPT);
class UI extends React.Component{
	render(){
		return(
			<div>
			  <p>{this.props.name}</p>
			  <p>{this.props.num}</p>
			  <OPT/>
			</div>
		)
	}
}
function getState(state){
	return state;
}
UI = connect(getState)(UI);
ReactDOM.render(<Provider store={store}><UI name={name}/></Provider>,
	document.getElementById('test'));

react-redux的实现:

Provider组件主要有以下下两个作用
        在整个应用上包一层,使整个应用成为Provider的子组件
        接收Redux的store作为props,通过context对象传递给子组件,所有的子组件都可以通过this.context.store取得store

import React from 'react'
import PropTypes from 'prop-types'

export class Provider extends React.Component{
    static childContextTypes = {
        store: PropTypes.object
    }
    constructor(props, context){
        super(props, context)
        this.store = props.store
    }
    getChildContext(){
        return {store:this.store}
    }
    render(){
        return this.props.children
    }
}

connect实现:

import React from 'react';
import {bindActionCreators} from 'redux';
import PropTypes from 'prop-types';

export const connect = (mapStateToProps=state=>state,mapDispatchToProps={}) => (WrappedComponent) => {
  class Connect extends React.Component {
    static contextTypes = {
      store: PropTypes.object
    }
    constructor(props,context){
    	super(props,coontext);
    	this.state={
    		props:{}
    	}
    }
    componontDidMount(){
    	const {store} = this.context;
    	store.subscribe(()=>this.update());
    	this.update()
    }
    update(){
    	const {store} = this.context;
    	const stateProps = mapStateToProps(store.getState());
    	const dispatchProps = bindActionCreators(mapDispatchToProps,store.dispatch)
    	this.setState({
    		props:{
    			...this.state.props,
    			...stateProps
    			...dispatchProps
    		}
    	})
    }
    render () {
      const { store } = this.context
      let stateProps = mapStateToProps(store.getState())
      return <WrappedComponent {...this.state.props} />
    }
  }
使用了react-redux后,组件可以通过this.props得到store的状态
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值