react+redux实战——redux到底是个啥子?
寫在前面
文章是個人初學redux的分享,從redux基礎知識點到使用redux搭建簡單的表單提交項目。
項目代碼地址:https://github.com/jishuaizhen/react-redux-simple-project.git
項目學習視頻:https://ke.qq.com/course/368915
一、redux到底是個啥子?
1.redux和vuex具有類似的作用,為了方便組件間的數據通信而產生。
2.簡單理解:redux和vuex都提供了一個數據倉庫,組件無法直接修改倉庫中的數據,需要使用redux中提供的方法傳參修改或者獲取數據。
3.注意:redux涉及到三個比較重要的點:store、action、reducer;另外,在使用redux的時候參數也是傳來傳去的,比較麻煩,容易繞暈。
4.redux的詳細介紹:阮一峰老師的博客http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html
5.
在圖中可以看到,使用redux之后:1.用戶觸發組件中的事件,需要提交或者獲取數據;2.action接到用戶的操作并派發;3.action在派發過程會經過store,攜帶store中的數據和action(具體操作)提供給reducer;4.reducer處理之后返回最新的狀態(也就是數據),更新store中的數據;5.當store發生變化之后,組件獲取數據進行頁面渲染。
二、react+redux實戰
1.這里是我學習練習的一個小案例,框架使用create-react-app,請求的接口使用http://jsonplaceholder.typicode.com/posts
2.頁面布局
頁面上方是添加標題和內容的文本框,頁面下方是請求接口的數據
3.主文件App.js
組件文件在components文件夾中,actions負責操作分發,reducers負責數據的處理,store.js負責
三、分步操作
1.Posts.js組件
fetch('http://jsonplaceholder.typicode.com/posts').then(res=>res.json()).then(posts=>{this.setState({posts:posts})})//通過請求獲取數據渲染到頁面2.PostsForm.js組件
//渲染功能 render() {return (<div><h1>添加內容</h1><form onSubmit={this.onSubmit}><div><label>title</label><br/><input type="text" name="title" onChange={this.onChange} value={this.state.title}></input></div><div><label>body</label><br/><textarea name="body" onChange={this.onChange} value={this.state.body}></textarea></div><br/><button type="submit">添加</button> </form></div>)}...//綁定函數onChange=(e)=>{console.log(e.target)this.setState({[e.target.name]:e.target.value})}onSubmit=(e)=>{e.preventDefault()const post = {title:this.state.title,body:this.state.body}}//數據請求fetch('http://jsonplaceholder.typicode.com/posts',{method:'POST',header:{"content-type":"application/json"},body:JSON.stringify(postData)}).then(res=>res.json()).then(data=>{console.log(data)})3.初識store
1.npm i redux react-redux redux-thunk 2.使用redux是為了狀態(數據)的統一管理,為了讓所有組件拿到狀態,需要使用<Provider></Provider>將根組件包裹 import {Provider} from 'react-redux'function App() {return (<Provider store={store}><div className="App"><PostForm></PostForm><Posts></Posts></div></Provider>); } 3.創建store, Redux 應用只有一個單一的 store。當需要拆分數據處理邏輯時,你應該使用 reducer 組合而不是創建多個 storeimport {createStore,applyMiddleware,compose} from 'redux' import thunk from 'redux-thunk' import rootReducer from './reducers/index' const initialState = {} const middleware = [thunk] //createStore可以傳三個參數:1.多個reducer對象;2.初始狀態為空對象,當調用redux之后會返回一個新的對象;3.中間件applyMiddlewares是 Redux 的原生方法,作用是將所有中間件組成一個數組,依次執行 export const store = createStore(rootReducer,initialState,applyMiddleware(...middleware) )4.Reducer和CombineReducers
1.Reducer Store 收到 Action 以后,必須給出一個新的 State,這樣 View 才會發生變化。這種 State 的計算過程就叫做 Reducer。Reducer 是一個函數,它接受 Action 和當前 State 作為參數,返回一個新的 State。export default function(state=initialState,action){switch(action.type){default:return state;} }2.Reducer 的拆分 Reducer 函數負責生成 State。由于整個應用只有一個 State 對象,包含所有數據,對于大型應用來說,這個 State 必然十分龐大,導致 Reducer 函數也十分龐大,所以需要拆分Reducer。//在創造store過程中rootReducer是多個對象 export const store = createStore(rootReducer,initialState,applyMiddleware(...middleware) )3.CombineReducers 這樣一拆,Reducer 就易讀易寫多了。而且,這種拆分與 React 應用的結構相吻合:一個 React 根組件由很多子組件構成。這就是說,子組件與子 Reducer 完全可以對應。 Redux 提供了一個combineReducers方法,用于 Reducer 的拆分。你只要定義各個子 Reducer 函數,然后用這個方法,將它們合成一個大的 Reducer。import {combineReducers} from 'redux' import postReducer from './postReducer'export default combineReducers({posts:postReducer })5.actions和types
1.我們需要在actions文件夾里面定義操作的函數,然后在組件內進行調用。重點:這一步就是將原本存在在組件中的操作(數據請求等)轉移到actions中。組件調用actions中的方法就需要使用connect建立鏈接,React-Redux 提供connect方法,用于從 UI 組件生成容器組件。connect的意思,就是將這兩種組件連起來。import { connect } from 'react-redux' import { fetchPosts } from '../actions/postActions'const mapStateToProps = state => ({posts:state.posts.items,newPost:state.posts.item }) export default connect(mapStateToProps,{fetchPosts})(Posts);2.現在我們可以通過組件調用actions里面的方法重點:redux需要actions的dispatch分發操作攜帶方法和store中的狀態交給reducer進行處理,reducer返回更新后的狀態(數據),組件進行更新。actions中有多種操作,所以在dispatch分發操作時需要配置action的types屬性進行分辨執行哪個操作。//創建types.js文件,types文件就是為不同action定義不同名字,需要在actions和reducers文件中引入,以便讓reducer知道解決哪一種操作 export const FETCH_POSTS = "FETCH_POSTS"; export const NEW_POSTS = "NEW_POSTS"; 3. //postActions.js文件 export const fetchPosts = () => dispatch => {fetch('http://jsonplaceholder.typicode.com/posts').then(res=>res.json()).then(posts=>// 當操作成功時,通過dispatch攜帶action.type和請求到數據給store,store告訴postReducer.js進行操作,返回處理后的狀態dispatch({type:FETCH_POSTS,payload:posts})) } //postReducer.js export default function(state=initialState,action){switch(action.type){case NEW_POSTS:return {...state,item:action.payload}case FETCH_POSTS:return {...state,items:action.payload}default:return state;} }6.mapState獲取最新狀態
1.postReducer.js接收到action.type和請求到數據進行處理返回新的狀態,這里reducer處理action操作得到的數據進行處理返回新的數據給store。2.store中的數據更新,組件需要想辦法進行接收。 mapStateToProps()是一個函數。它的作用就是像它的名字那樣,建立一個從(外部的)state對象到(UI 組件的)props對象的映射關系。const mapStateToProps = state => ({posts:state.posts.items }) export default connect(mapStateToProps,{fetchPosts})(Posts);3.另外redux要求我們需要給方法和狀態規定數據類型 import PropTypes from 'prop-types' //使用方法 Posts.proptypes = {fetchPosts:PropTypes.func.isRequired,posts:PropTypes.array.isRequired }7.添加數據
1.接收到文本框的數據PostForm.js onSubmit=(e)=>{e.preventDefault()const post = {title:this.state.title,body:this.state.body}// 觸發actionthis.props.createPost(post)}2.PostActions.js接收到操作通知export const createPost = postData => dispatch => {fetch('http://jsonplaceholder.typicode.com/posts',{method:'POST',header:{"content-type":"application/json"},body:JSON.stringify(postData)}).then(res=>res.json()).then(post=>// 當操作成功時,通過dispatch將數據和action.type交給postReducer.js處理dispatch({type:NEW_POSTS,payload:post})) } 3.postReducer.js根據對應的操作返回處理后的數據 export default function(state=initialState,action){switch(action.type){case NEW_POSTS:return {...state,item:action.payload}case FETCH_POSTS:return {...state,items:action.payload}default:return state;} } 4.數據更改后,Post.js接收數據進行渲染 const mapStateToProps = state => ({posts:state.posts.items,newPost:state.posts.item //這里是添加的數據 })寫在最后
1.自認為redux比vuex復雜些,操作和數據類型要求的更規范些
2.官方將store中的數據定義為狀態,狀態改變即為數據更新,所以文章中有些地方使用狀態和數據兩種說明
3.使用redux后操作和數據請求不在組件中進行,而是交給actions和reducers,reducers將數據處理后返回給store,store通過mapStateToProps()方法將store中的數據對象和UI組件中的props進行映射,props改變導致頁面進行重新渲染
建議:個人是初學者,很多地方描述不太準確。大家可以先看一下學習視頻和阮一峰老師的博客,然后可以看一下我的文章,有什么不準確的地方可以留言說明。
總結
以上是生活随笔為你收集整理的react+redux实战——redux到底是个啥子?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 药物研发常用数据库
- 下一篇: js中公有方法、特权方法、静态方法