Code Monkey home page Code Monkey logo

reduxtodo's People

Contributors

rocketv2 avatar

Watchers

 avatar  avatar

reduxtodo's Issues

#总结 减少ref的使用

项目中ref属性的作用

ref主要是用来获取dom对象,尤其是表单元素,如下代码:

<form onClick={this.eventHandler} onKeyDown={this.eventHandler} >
	<input type="text" ref={this.refDom} />
	<button type='submit'>add</button>
</form>

想获取input元素的值,显然不能使用jQuery的方式通过选择器来获取;而ref属性能够将dom对象作为形参传入函数中,此时函数this.refDom的形参就是input对象;

为何减少ref的使用

react采用虚拟DOM的目的是:减少DOM操作;但是ref属性操作的正是实际的DOM,这与react的理念相违背;

如何减少ref的使用

采用受控表单的方式;

<input type="text" value={this.state.getInputVal} onChange={this.getInputVal}  />

#总结 项目开发中注意的小细节

props 数据类型检查

项目中使用了prop-types库进行静态数据类型检查;这个是开发中必不可少的操作之一,能够降低引入bug的概率;

在产品环境中如何去掉prop-types库?
可以借助 babel-plugin-transform-react-remove-prop-types

在React v15.5.0 中,官方已经将 propTypes 从React库中独立出来,放在prop-types库中;这样做好处是:产品环境时并不使用propTypes进行检查,只是在开发环境中作为辅助工具,因此在产品环境中没必要使用这个库,减少上线代码体积;React把PropTypes放到一个独立包

pubsub.js

组件父子之间通信 我们通常采用props,但是如果两个组件没有关联,比如是兄弟组件,如何在两者之间进行通信?通常做法是,找到这两个组件最近的父组件,进行状态提升,完成通信;

如果不想通过状态提升的方式,如何完成通信呢? 这就是pubsub.js库的作用,采用观察者模式,订阅事件后,如果某个组件发布这个事件,就能够触发订阅事件了;

pubsub库接口简单:publish(), subscribe(), unsubscribe()等;具体 官文文档
注意点:在componentWillUnmount钩子中要调用unsubscribe()

json5 格式

开发过程中如果需要使用静态数据,json格式是必不可少的选择;但是json在格式上存在一定的限制,比如书写格式限制等,不是很接近javascript语言风格;而json5正好解决了这个痛点,json5是JavaScript的子集,可以看做是对象类型,操作起来十分方便;

具体可以参考 json5官网

JSX、HTML语法注意

  1. jsx 注释用法: {/* 代码 */}
  1. 所有的标签都是闭合标签
  1. 使用内联样式时,style属性必须使用 {{}},第一层{}是表达式,第二次是传入的样式对象
<div style={{width: 20px; height=30px}}>
    { props.text }
</div>

#总结 为何要引入redux

单纯使用react开发组件遇到的困境

比如开发todo组件,组件分成两部分:1. 添加 2. 展示;这两个部分是两个小组件;

如何将 组件1 中数据传入到 组件2 中呢?

通常采用 状态提升(lifting state up) 的方式;具体见 状态提升

但是,这种方式没有 状态管理 ,如果组件比较多,state就显得比较混乱;

因此引入了 redux 状态管理; redux 单向数据流,采用几个简单的API来控制数据单向流动;同时采用单一store,所有的组件都从唯一store中获取数据;

redux 生态

围绕redux状态管理有许多知识点要掌握;

  1. redux 基础API、工作流程

  2. redux 中间件;重点为 异步请求的处理

  3. react-redux的使用;为何引入react-redux?使用它带来了什么好处?

redux 基础API、工作流程

redux 中几个核心的概念: store,dispatch,subscribe,action

从redux库中引入的函数为 createStore,combineReducers,applyMiddleware,compose

  1. 通过createStore创建的对象包含以下接口
  • dispatch 分发action

  • getState 获取Store

  • subscribe 监听state,如果有改动,刷新函数

  1. combineReducers 将分割的reducer合并成一个reducer;

基于此,在设计store状态树时,要保持扁平化风格,尽量少些层级

  1. applyMiddleware 中间件

经常用于异步处理的中间件 redux-thunk
用于检测reducer是否是纯函数的中间件 redux-immutable-state-invariant

  1. compose 增强器

关于这部分基础,可以查看官方文档 ;也可以阅读 阮老师redux系列三篇

为何要引入 redux-redux ?

先说下,如果只使用redux提供的API,基本能够完成项目开发;
但是会遇到如下两个问题:

  1. 每次在组件中使用state时,都要引入store,通过store.getState()获取状态树;

  2. 每个组件为了便于开发,都采用 “UI组件 + 容器组件”的形式,其中UI组件负债UI展示,容器组件负责业务逻辑、数据处理(即dispatch action);但是容器组件结构简单,需要重复书写,如下:

/**
 * UI组件
 */
const ListItem = ({itemInfo,changeStatus}) => {

	let liItem = itemInfo.map((item,index)=>{
		return (
			<li 
				key={index}
				onClick={changeStatus}
			>
				{item.text}
			</li>
		);
	});
	return (
		<ul>
			{liItem}
		</ul>
	);
}
ListItem.propTypes = {
	itemInfo: PropTypes.array.isRequired,
	changeStatus: PropTypes.func.isRequired
}

/**
 * 容器组件
 */
class Container extends React.Component{
	constructor(){
		super(...arguments)
		this.state = {
			todos: Store.getState().todos
		}
		this.changeState = this.changeState.bind(this)
	}

	changeState(){
		this.setState({
			todos: Store.getState().todos
		});
	}

	componentDidMount(){
		Store.subscribe(this.changeState);
	}

	changeStatus(){
		console.log('改变组件状态 完成、删除')
	}

	render(){
		const items = this.state.todos;
		return (
			<ListItem 
				itemInfo={items}
				changeStatus={this.changeStatus}
			/>
		);
	}
}

react-redux 库解决了这两个问题,库提供了两个接口: Provider connect;
Provider 能够提供全局的store
connect 能够生成容器组件,开发者只需要提供UI组件即可;

快速入门 阮老师react-redux

#问题 使用redux-thunk处理异步时,回调函数无法执行

在容器组件中dispatch回调函数,使用redux-thunk作为中间件,发现并未执行回调函数;代码如下:

const mapDispatchToProps = (dispatch) => {
	return {
		addItem: (val) => {
			// 使用redux-thunk中间件
			dispatch((val)=>{
				return (dispatch,getState) => {
					// 并未执行此处代码,在此进行异步处理
				}
			});
		},
	}
}

在dispatch中return的函数并未执行,因此无法进行异步处理
此问题困住了我很久,因为官方代码:

function incrementAsync() {
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      dispatch(increment());
    }, 1000);
  };
}

一直受这段代码影响,以为incrementAsync函数为disapcth的参数,redux-thunk中间会执行该函数;但实际结果跟猜测不一致,incrementAsync中的 return 返回的函数根本没有执行;无奈,只能看redux-thunk源码了,源码如下:

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

从源码中可以看出,dispatch的函数就是redux-thunk要回调的函数,形参是dispatch,getState;不需要return函数,redux-thunk不会执行return中的函数;正确的写法如下:

const mapDispatchToProps = (dispatch) => {
	return {
		addItem: (val) => {
			// 使用redux-thunk中间件
			dispatch((dispatch,getState) => {
				// 并未执行此处代码,在此进行异步处理
			});
		},
	}
}

以上是本人的理解,如有疑问,欢迎交流~~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.