react專案用@connect裝飾器
阿新 • • 發佈:2020-12-21
conncet是從react-redux中結構出來的一個裝飾器,用來實現不同頁面(或元件)的資料共享,避免元件間一層層的巢狀傳值。
為何要使用@connect裝飾器
在安裝完redux,react-redux之後雖然可以輕鬆的完成資料共享,但是程式碼及其麻煩。
例如在index.js裡這樣寫:
import thunk from 'redux-thunk' import {createStore,applyMiddleware,compose} from 'redux' import {reducer} from './reducer/index.js' import {Provider} from 'react-redux' const devToolsExtension = window.__REDUX_DEVTOOLS_EXTENSION__ ? window.__REDUX_DEVTOOLS_EXTENSION__() : ()=>{} const store = createStore( reducer, compose( applyMiddleware(thunk), devToolsExtension ) ) ReactDOM.render( <Provider store={store}> <App /> </Provider>, document.getElementById('root') );
上面這段程式碼只是抽出了引用部分,表示如何在下載redux,redux-thunk(一個允許在redux裡做非同步操作的庫),react-redux的react專案裡使用。
在App.js裡這樣寫:
//{addNum,rmNum,removeAsync} 這部分是自定義的改變redux返回的state狀態的函式的引入,屬於業務需求部分 import {addNum,rmNum,removeAsync} from './reducer/index.js' import {connect} from 'react-redux' //然後把redux管理的狀態和自定義方法對映到App元件的this.props中去。 const mapStateToProps = (state) => { return {abc:state} } const mapDispatchToProps = {addNum,rmNum,removeAsync} App = connect(mapStateToProps,mapDispatchToProps)(App)
然而,這並不是最簡潔和最順手的寫法,在最簡潔的寫法中你只需要如下程式碼,就可以實現redux管理的資料共享:
//connect()裡的第一個引數是一個函式,作用和上一段程式碼的mapStateToProps作用相同,第二個引數是一個物件,可以傳入你需要共享的函式 @connect( state=>({abc:state}), {addNum,rmNum,removeAsync} )
雖然看上去也沒少多少,但這種寫法寫起來更加順手在很多元件都需要使用的時候可以減少更多程式碼,這絕對是最快捷的方法,這裡說的最快捷是指在使用redux和react-redux的情況下,如果有槓精非要說可以用hook實現資料共享,那你就去用hook吧,還看什麼react-redux?
那麼如何實現@connect裝飾器的使用呢?
- 在命令列工具中使用 npm run eject。不熟的情況下可能會報錯,如果報錯的資訊大概意思是:有些檔案未被追蹤到,那麼直接git add . 再 git commit -m"",或者直接在.gitignore中忽略這些檔案(不建議)
- npm run eject之後package.json中會出現很多依賴建議yarn/npm i 一下。
- 然後開啟package.json檔案,找到“babel”開頭的一個物件,(一般在最後,),這是原始的樣子:
"babel": { "presets": [ "react-app" ] }
加入另外一項:
"babel": { "presets": [ "react-app" ], "plugins": [ [ "@babel/plugin-proposal-decorators", { "legacy": true } ] ] }
接著就可以在不同元件中引入:
import {connect} from 'react-redux'
然後使用@conncet裝飾器:
//這裡沒用第二個引數,因為沒有需要引入需要的函式 @connect( state=>({abc:state}) )
差不多就這樣了。
雖然只有三步,但可能出現毛毛多的報錯,如果遇到不會的可以給我留言,或者複製報錯資訊百度,都能解決。
再解決之後一定要記住解決的方法,我也不知道為什麼要這樣說,可能之後會再次遇到吧。