学习react之使用redux实现todoList
在学习完react基础知识后,就用简单的一个小例子来稍微实战下,之前没有系统的学习过现在重新来过,一步步了解react的相关知识。react是一个js库,提倡组件化编写代码,可以把项目分成多个组件组成一个小的项目,本身只是一个js库,数据与UI分开的模式使得更便于维护以及多人开发,初开始用的时候会觉得很麻烦,尽管只是一个小功能都会分为好几个部分,真正习惯了之后会发现想当的便捷,现在我们就从一个简单todoList开始。
这个实例主要是为了熟悉
redux
所以最基础的内容可能需要大家稍微了解下react官网的内容,基础知识要稍微知道点.
技术栈
- react
- redux
- redux-thunk
- react-redux
- antd
开始初始化项目
这里开始初始化一个项目,使用的是create-react-app
,运行 npm install create-react-app -g
全局安装,然后运行create-react-app demo
创建一个名为demo
的react项目,这里是会直接下载依赖的所以可以直接运行npm start
启动项目,
到这里就已经成功创建并启动了一个react项目.
然后安装redux
的相关依赖,运行npm install --save redux redux-thunk react-redux antd
,这里的redux是为了统一管理组件的数据,将所有的
state数据存储在一个单一的数据源store内部,相当于就是一个全局对象。redux-thunk
是redux的中间件,相当于一个对redux的增强,redux只能处理同步的数据,因此
涉及到异步的数据就需要这个中间件进行处理了.react-redux
是为了将react和redux联合起来的,因为这两个库是独立的,需要使用这个库对他们进行绑定,是react的组件
能够从redux store
中读取数据,并且想store
分发action
以更新数据
正式的代码
入口的代码
// src/index.js
import React from 'react'
import ReactDOM from 'react-dom';
import * as serviceWorker from './serviceWorker';
// todoList组件
import TodoList from './TodoList'
import { Provider } from 'react-redux'
// 获取store的数据
import store from './store/index'
ReactDOM.render(
// 这里的provider就是react-redux提供的组件,能够使其子组件都能访问到store中的数据
<Provider store={store}><TodoList /></Provider>, document.getElementById('root'));
serviceWorker.unregister();
store的初始化代码
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk'
import reduce from './reduce/index'
// 这是增强函数,__REDUX_DEVTOOLS_EXTENSION_COMPOSE__是为了能够使用redux devtools
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ ?
window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({}):compose
// 创建store并且使用redux-thunk中间件
const store = createStore(reduce,composeEnhancers(applyMiddleware(thunk)))
export default store
然后就是创建reducer
// src/store/reduce/todo.js
// 引入定义的常量
import { ADD_ITEM, CHANGE_INPUT, DELETE_ITEM } from '../actionTypes'
// 默认数据
const defaultState = {
inputValue: 'aabb',
list: ['列表一','第二项']
}
// 输出reducer,其实就是一个函数,根据aciton修改state,因为store中的数据只允许在reducer中修改
export default (state = defaultState, action) => {
let newState = JSON.parse(JSON.stringify(state))
switch (action.type){
case CHANGE_INPUT:
newState.inputValue = action.value;
return newState;
case ADD_ITEM:
newState.list = [...newState.list,newState.inputValue]
newState.inputValue = ''
return newState
case DELETE_ITEM:
newState.list.splice(action.index,1)
return newState
default:
return state;
}
}
然后就是如何在todoList组件中使用这些store中的数据了
import React, { Component } from 'react';
// 使用antd一个UI库,推荐按需引入
import { Button, Input, List } from 'antd'
import 'antd/dist/antd.css'
// 在入口处我们使用了react-redux的Provider,在组件中要使用connect使他们关联起来,然后组件中就能使用store数据了
import { connect } from 'react-redux'
// 组件中会把所有对stroe数据的改动的函数提取出来作为单独的一个文件分开来写,方便维护,这些函数是要注册到connect中的
import { changeInput, addItem, deleteItem } from './store/actions/todo'
class TodoList extends Component{
render(){
// 引入provider传入的store中的数据,这里包含state数据也包含对数据处理的函数
const { inputValue, list, changeInput, addItem, deleteItem } = this.props
return (
<div>
<div>
<Input value={inputValue} style={{width: '300px',margin: '30px'}} onChange={changeInput}></Input>
<Button onClick={addItem}>增加</Button>
</div>
<ul>
{
list.map((item,index) =>{
return (
<li key={index} onClick={() => deleteItem(index)}>{item}</li>
)
})
}
</ul>
</div>
)
}
}
const stateToProps = (state) => {
return {
inputValue: state.todo.inputValue,
list: state.todo.list
}
}
// connect包含的两个参数,第一个是state中处理的数据,第二个是action creaters构成的对象,就是对数据处理的函数构成的对象。
// connect返回一个函数用来接收一个待包装的组件
export default connect(stateToProps, { changeInput, addItem, deleteItem })(TodoList)
完整代码请参考github地址