react连接mysql_react+redux教程(⼋)连接数据库的redux程
序
前⾯所有的教程都是解读官⽅的⽰例代码,是时候我们⾃⼰写个连接数据库的redux程序了!
例⼦
这个例⼦代码,是我⾃⼰写的程序,⼀个⾮常简单的todo,但是包含了redux插件的⽤法,中间件的⽤法,连接数据库的⽅法等多个知识点。
源代码:
运⾏⽅法:
npm install
npm run build
⼿动打开index.html
wilddog数据库
作为⼀名曾经的angular开发者,我⾮常喜欢⽤firebase来做⾃⼰的数据库,并结合angular实现酷炫的“三向数据绑定”。wilddog是中国的“firebase”,不仅语法兼容,⽽且国内速度更快。
下⾯的程序都是基于wilddog和angular的程序,也⽤了我曾经的最爱requirejs,有兴趣的同学可以看看,顺便赏我点star哈哈!
如今写react程序,仍然可以使⽤wilddog或者firebase,不仅不⽤配置数据库服务,也不⽤写数据库增删改查的api程序了,可以让我们前端⼯程师专注于写前端程序!
redux的chrome插件
本程序也⽤到了redux的chrome插件,可以帮助我们⾃动⽣成redux的devtool界⾯,⾮常好⽤啊!只需要在你的程序store注册中,加⼊⼀⾏代码:
export default (initialState) =>{
const store=compose(
applyMiddleware(
thunk,
createLogger()
),
window.devToolsExtension? window.devToolsExtension() : f =>f
)(createStore)(reducers, initialState);returnstore;
};
就是这⾏代码:
window.devToolsExtension ? window.devToolsExtension() : f => f
安装⽅法,就是去chrome的市场搜索redux关键字就可以了!
没有服务端渲染和热替换
为什么要把这个单独提起来说呢?这是⼀个历史遗留问题。我们研究所⽤的web框架是flask,⼀个python框架,包括前端也是⽤flask的jinja模板。没有nodejs也就意味着⽆法使⽤服务端渲染和热替换这两个炫酷的功能。
那么不是基于nodejs的前端程序,还能否使⽤redux和react呢?当然可以,我只通过webpack⽣成⼀个js⽂件,将js⽂件放进html⾥⾯。其他所有的功能都不要。这也是可以的。这也算是结合⾮node平台的⼀个实践经验吧!当然你的包管理还得⽤npm。
从另⼀个⽅⾯来说,基于nodejs的前端时代已经来临,如果你拒绝它,将会失去很多,或者⼨步难⾏!
dom4j读取解析xml获取所有的todos
我们在action中进⾏http请求和服务端交互,即便是在中间件中执⾏http请求,其实质也是dispatch的封装。那么这个程序的关键就是action的编写。
实例化wilddog,定义action类型:
actions.js
import Wilddog from 'wilddog/lib/wilddog-node'
/** action 类型*/export const GET_TODO_ERROR= 'GET_TODO_ERROR';
export const GET_TODO_OK= 'GET_TODO_OK';
export const ADD_TODO_ERROR= 'ADD_TODO_ERROR';
export const ADD_TODO_OK= 'ADD_TODO_OK';
export const REMOVE_TODO_OK= 'REMOVE_TODO_OK';
export const REMOVE_TODO_ERROR= 'REMOVE_TODO_ERROR';
let wilddog=new Wilddog('redux-wilddog-todos.wilddogio')
从wilddog数据库中获取所有的todos,因为wilddog数据库是树状结构,⽣成的列表,其实质也是个对象,所以我们需要将其转化为数组:
export functiongetTodo() {return (dispatch,getState)=>{
wilddog.child('todos').once('value',(snapshot)=>{
box shadow怎么设置let obj=snapshot.val();
let array=[];for(let key inobj){
array.push({key:key,text:obj[key].text})
}
dispatch({
type: GET_TODO_OK,
payload: array
})
},(err)=>{
dispatch({
html基础代码免费type: GET_TODO_ERROR,
payload: err
})
});
}
}
触发器 select into
mysql菜鸟教程增删改查wilddog.child('todos').once('value',function)是获取‘todos’节点数据的⽅法。获取到数据后,转化为数组。然后dispatch⼀个GET_TODO_OK,告诉reducer获取数据成功,可以更新state了。数据都装在payload中。如果失败,则dispatch⼀
GET_TODO_ERROR。
就是这么简单,不⽤写后台程序,在js中直接操作数据库!
那么在哪⾥执⾏这个getTodo呢?你可以在组件渲染后dispatch它,也可以在初始化store后,⽴即执⾏它。我⽤的是后⾯⼀种:
index.js
import { getTodo,registerListeners} from './actions'let store=createStore();
store.dispatch(getTodo())
添加新的todo
在action中定义添加todo的⽅法:
actions.js
export functionaddTodo(text) {return (dispatch,getState)=>{
wilddog.child('todos').push({
text
},(err)=>{if(err){dispatch({type:ADD_TODO_ERROR,payload:err})}
});
}
}
通过wilddog.child('todos').push()⽅法,直接往数据库中插⼊数据,第⼆参数是回调,失败的话,dispatch相应的action。
那么成功后的action在哪执⾏?我们需要再写⼀个function,绑定数据变动的回调。其实正常情况下,我们在这个function中就直接写成功后的回调了,主要是因为wilddog数据库的成功回调不在push这个
⽅法中。
actions.js
export functionregisterListeners() {return (dispatch, getState) =>{
wilddog.child('todos').on('child_removed', snapshot =>{
dispatch({
type: REMOVE_TODO_OK,
payload: snapshot.key()
})
});
wilddog.child('todos').on('child_added', snapshot =>dispatch({
type: ADD_TODO_OK,
payload: Object.assign({},snapshot.val(),{key:snapshot.key()})
}));
};
}
wilddog.child('todos').on('child_added') 这个⽅法定义了添加todo成功后的回调,我们执⾏了⼀个ADD_TODO_OK 的action,并把新的todo对象放在payload中返回给reducer。
你也看到了,我们顺便把移除todo成功的回调也定义了。
我们在哪执⾏这个绑定函数呢?就在获取所有todos的后⾯吧!其实放在组件渲染完也可以!
index.js
store.dispatch(registerListeners())
移除指定todo
在action中添加移除todo的⽅法:
actions.js
export functionremoveTodo(key) {return (dispatch,getState)=>{
wilddog.child(`todos/${key}`).remove((err)=>{
if(err)dispatch({type:REMOVE_TODO_ERROR,payload:err})
});
}
}
通过wilddog的remove⽅法移除数据库的指定节点。就是这么简单!然后编写失败后的回调以及action!
数据库在action中完事,state还需要reducer
数据库我们是操作完啦,不过组件的显⽰是基于state的,我们还要同步更新state,那么reducer就出场了!
reducers.js
import { combineReducers } from 'redux'import { ADD_TODO_OK, REMOVE_TODO_OK ,GET_TODO_OK} from'./actions'
function todos(state=[], action) {pe) {caseGET_TODO_OK:returnaction.payloadcaseADD_TODO_OK:return[
...state,
action.payload
]caseREMOVE_TODO_OK:return state.filter((todo)=>todo.key!==action.payload
)default:returnstate
}
}
const todoApp=combineReducers({
todos
})
后台管理系统模板如何使用exportdefault todoApp
很简单,如果你还不会,可以去前⾯⼏节教程补课。
来个图吧:
action操作数据库后,要在回调中返回信号,让reducer更新state,因为只有state变了,组件才会变。state变了,组件⾃动就变了,⾄少不⽤苦逼地操作dom了,还是挺开⼼的!
为什么不提react组件
说了这么多我们的redux容器算是搞定了,为什么不提组件?不是不提,是要让⼤家知道,组件和redux容器的耦合度很低,我们可以完全将它们隔离开来编写,通过⼀些固定的套路将它们连接起来。什么套路?
绑定state到props
绑定action到props(可选)
将store注⼊,并⽤provider在顶层包住组件
redux是个状态容器,只能通过发起action改变state,这种集中管控的做法让状态管理和预测变的简单。组件只是state的展现形式⽽
已!react只是⼀个界⾯库⽽已!
教程源代码及⽬录
如果您觉得本博客教程帮到了您,就赏颗星吧!
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论