react+redux+react-redux练习项目
一,项目目录
二、1、新建pages包,在pages中新建TodoList.js;
2、新建store包,在store包中新建store.js,reducer.js,actionCreater.js,actionType.js;
3、在public包中新建list.json
三、安装redux,react-redux,axios
yarn add redux --save, yarn add react-redux --save,yarn add axios --save
四、index.js
1 import React from 'react'; 2 import ReactDOM from 'react-dom'; 3 import './index.css'; 4 import * as serviceWorker from './serviceWorker'; 5 import { Provider } from 'react-redux' 6 import TodoList from './pages/TodoList' 7 import store from './store/store' 8 9 const App =( 10 <Provider store={store}> 11 <TodoList /> 12 </Provider> 13 ); 14 ReactDOM.render(App, document.getElementById('root')); 15 16 // If you want your app to work offline and load faster, you can change 17 // unregister() to register() below. Note this comes with some pitfalls. 18 // Learn more about service workers: https://bit.ly/CRA-PWA 19 serviceWorker.unregister();
使用react-redux。在react-redux的使用中,关注两个方法:Provider和connect
- Provider把store放到context里,所有的子元素可以直接取到store(<TodoList/>和其他所有添加在<Provider></Provider>中的组件),本质上 Provider 就是给 connect 提供 store 用的。
- connect 是一个高阶组件,接受一个组件 WrappedComponent 作为参数,负责链接组件,把给到redux里的数据放到组件的属性里。主要有两个作用:1. 负责接受一个组件,把state里的一些数据放进去,返回一个组件;2. 数据变化的时候,能够通知组件
五、store.js
1 import { createStore,applyMiddleware,compose} from 'redux'; 2 import reducer from './reducer'; 3 import thunk from 'redux-thunk'; 4 5 6 //添加redux工具 7 const composeEnhancers= window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__() 8 9 const enhancerss = compose( 10 applyMiddleware(thunk),composeEnhancers 11 ); 12 const store=createStore(reducer,enhancerss); 13 14 export default store;
引入redux-thunk中间件 他允许你的action可以返回函数和对象(不使用中间件只能返回对象), 带有dispatch和getState两个参数, 在这个action函数里, 异步的dispatch action;
六、reducer.js
1 const defaultState={ 2 inputValue:'', 3 list:[] 4 } 5 6 export default (state=defaultState,action)=>{ 7 8 switch(action.type){ 9 case "change_input_value": 10 { 11 const newState =JSON.parse(JSON.stringify(state)) 12 newState.inputValue=action.value; 13 return newState; 14 } 15 case "add_item": 16 { 17 const newState =JSON.parse(JSON.stringify(state)) 18 newState.list.push(newState.inputValue) 19 return newState 20 } 21 case "init_list_action": 22 { 23 const newState=JSON.parse(JSON.stringify(state)); 24 newState.list=action.data; 25 return newState; 26 } 27 case "delete_item": 28 { 29 const newState=JSON.parse(JSON.stringify(state)); 30 newState.list.splice(action.index, 1) 31 return newState; 32 } 33 default: 34 return state 35 } 36 37 }
七、actionType.js
1 export const CHANGE_INPUT_VALUE='change_input_value' 2 export const ADD_ITEM='add_item' 3 export const INIT_LIST_ACTION='init_list_action' 4 export const DELETE_ITEM='delete_item'
八、actionCreater.js
1 import axios from 'axios' 2 import {CHANGE_INPUT_VALUE,ADD_ITEM,INIT_LIST_ACTION,DELETE_ITEM} from './actionType' 3 4 5 export const initListAction = (data)=>({ 6 type: INIT_LIST_ACTION, 7 data 8 }) 9 10 11 export const deleteItem =(value)=>({ 12 type:DELETE_ITEM, 13 value 14 }) 15 export const additem =(value)=>({ 16 type:ADD_ITEM, 17 value 18 }) 19 20 export const changeValue =(value)=>({ 21 type:CHANGE_INPUT_VALUE, 22 value 23 }) 24 25 export const getTodoList=()=>{ 26 return(dispatch)=>{ 27 axios.get('./list.json').then((res)=>{ 28 const data=res.data 29 const action =initListAction(data) 30 dispatch(action); 31 }) 32 } 33 }
九、TodoList.js
1 import React from 'react'; 2 import store from '../store/store' 3 import { connect} from 'react-redux' 4 import {initListAction,getTodoList,additem,changeValue,deleteItem} from '../store/actionCreater' 5 6 7 class TodoList extends React.Component{ 8 constructor(){ 9 super(); 10 this.state=store.getState(); 11 } 12 13 14 componentDidMount(){ 15 const action=getTodoList(); 16 store.dispatch(action); 17 } 18 render(){ 19 const {list,inputValue,changeInputValue,handleAddClick,handleDelete} = this.props 20 return( 21 <div> 22 <div> 23 <input value={inputValue} onChange={changeInputValue}></input> 24 <button onClick={handleAddClick}>提交</button> 25 </div> 26 <ul> 27 <li> 28 { 29 list &&list.map((item,index)=>{ 30 return <li onClick={()=>{handleDelete(index)}} key={index}>{item}</li> 31 }) 32 } 33 </li> 34 </ul> 35 </div> 36 ) 37 } 38 } 39 40 41 const mapStateToProps =(state)=>{ 42 return { 43 inputValue:state.inputValue, 44 list:state.list 45 } 46 } 47 48 const mapDispatchToProps =(dispatch)=>{ 49 return{ 50 changeInputValue(e){ 51 const action=changeValue(e.target.value) 52 dispatch(action) 53 }, 54 //新增数据 55 handleAddClick(){ 56 const action =additem() 57 dispatch(action) 58 }, 59 //删除数据 60 handleDelete(index){ 61 const action=deleteItem(index) 62 dispatch(action) 63 } 64 } 65 } 66 export default connect(mapStateToProps,mapDispatchToProps)(TodoList);//和store做连接
十、list.json
["hello","nihao","haha"]