上一篇写了react实现todoList,并没有用到redux。这篇博客会介绍redux的核心部分和使用redux进行状态管理的开发过程。
redux的学习可以参考redux中文文档 ,这里简单带大家复习一下redux的核心部分:
(1)定义action:
action用来描述用户的行为,是一个对象。action是store数据的唯一来源,通过store.dispatch(action)可以更改state。
例如:我们可以定义action对象。
const action={
type:"ADD"
}
(2)定义reducer
reducer为一个返回值为对象的函数,用来定义操作的过程,根据action.type来进行state的更新。
例如,
const reducer=(state=0,action)=>{
switch(action.type){
case "ADD":
return state+1;
case "DEC":
return state-1;
default:
return state;
}
}
(3)创建store
store是一个用来存储数据的容器,可以通过createStore()方法创建store,通过getState()可以获取state对象:
import {createStore} from "redux"
const store=createStore(reducer)
const state=store.getState()
(4)Provider组件
Provider组件用来承载组件,利用provider组件可以将store注入到容器中。
<Provider store={store}>
<Add></Add>
<Todo></Todo>
<Done></Done>
</Provider>
(5)connect()
组件App可以通过export default connect()(App)方式来抛出。
下面开始项目开发..............
- 项目目录
- redux文件开发
1.store.js
import {createStore} from 'redux'
import reducer from './reducer'
const store=createStore(reducer)
export default store
//console.log('store:',store.getState())
2.reducer.js
const initstate={
list:[],
inputvalue:''
}
const reducer=(state=initstate,action)=>{
switch(action.type){
case 'INPUT':
const newstate=JSON.parse(JSON.stringify(state));
newstate.inputvalue=action.inputvalue;
return newstate;
//break;
case 'ADD':
const addstate=JSON.parse(JSON.stringify(state));
let list=Object.assign([],addstate.list);
list.push({
text:addstate.inputvalue,
id:new Date().getTime(),
status:false
})
addstate.list=list;
addstate.inputvalue='';
return addstate;
//break;
case 'FINISH':
const finishstate=JSON.parse(JSON.stringify(state));
let listf=finishstate.list.map(item=>{
if(item.id===action.id){
item.status=true
}
return item
})
finishstate.list=listf;
return finishstate
//break;
default:
return state;
}
}
export default reducer
- 组件开发
1.Add.js
import React,{Component} from 'react';
import './Add.css'
import {connect} from 'react-redux';
class Add extends Component{
constructor(props){
super(props);
this.handleChange=this.handleChange.bind(this);
this.handleClick=this.handleClick.bind(this);
}
handleChange(e){
const action={
type:'INPUT',
inputvalue:e.target.value
}
this.props.dispatch(action)
}
handleClick(){
if(!this.props.state.inputvalue)return;
this.props.dispatch(
{
type:'ADD',
}
)
}
render(){
return (
<div className="add">
<h1 className="logo">TodoList</h1>
<div className="addBox">
<input type="text" placeholder="添加任务" value={this.props.state.inputvalue} onChange={this.handleChange}></input>
<button onClick={this.handleClick}>添加</button>
</div>
</div>
)
}
}
export default connect((state)=>{
return {
state:state
}
})(Add);
2.Todo.js
import React,{Component} from 'react';
import './Todo.css'
import {connect} from 'react-redux';
class Todo extends Component{
constructor(props){
super(props);
this.handleDoneClick=this.handleDoneClick.bind(this)
}
handleDoneClick(index){
if(this.props.state.list[index].status===false&&this.props.state.list[index].id){
this.props.dispatch({
type:'FINISH',
id:this.props.state.list[index].id
})
}
}
render(){
return (
<div className="todo">
<h2>待完成事项</h2>
<ul>
{
this.props.state.list.map((item,index)=>{
return (
!item.status&&<li key={index}>
<span>{item.text}</span>
<button onClick={this.handleDoneClick.bind(null,index)}>Done</button>
</li>
)
})
}
</ul>
</div>
)
}
}
// connect抛出Todo
export default connect((state)=>{
return {
state:state
}
})(Todo);
3.Done.js
import React,{Component} from 'react';
import './Done.css';
import {connect} from 'react-redux';
class Done extends Component{
render(){
return (
<div className="done">
<h2>已完成</h2>
<ul>
{
this.props.state.list.map((item,index)=>{
return (
item.status&&<li key={index}><span>{item.text}</span></li>
)
}
)
}
</ul>
</div>
)
}
}
export default connect((state)=>{
return {
state:state
}
})(Done);
4.App.js
import React, { Component } from 'react';
import Add from './components/Add/Add';
import Todo from './components/Todo/Todo';
import Done from './components/Done/Done';
import {Provider} from 'react-redux'
import store from './redux/store'
class App extends Component {
render() {
return (
<div>
{/* 传入store */}
<Provider store={store}>
<Add></Add>
<Todo></Todo>
<Done></Done>
</Provider>
</div>
);
}
}
export default App;