相信用過React(或者React-Native,如下簡稱RN)的朋友對Redux
和Ref
這兩個概念都很熟悉,前者是開發React或RN比較經常使用的數據管理框架,固然不單單限於React或RN;後者是React提供的專門用於直接操做dom的接口,也能夠用來直接調用組件內的方法,固然用法也不單單限於這兩個。額...彷佛有點偏了,由於這兩個概念不是本文的重點因此不加贅述,有興趣的朋友能夠到官方文檔裏一睹廬山真面目。話很少說,下面開始進入正題吧,Let's Go!react
接下來我會用一個簡單的demo來演示這個問題是如何發生以及如何解決的:
首先新建一個Addition
組件,該組件用於顯示一個數值,而且能夠經過調用Addition
組件的addHandler
對這個數值進行+1
,主要代碼以下:git
class Addition extends Component { constructor(props) { super(props); this.state = { value: 0 } } addHandler = () => { this.setState({ value: this.state.value + 1 }) }; render() { return ( <div> <p>{this.state.value}</p> </div> ) } } export default Addition
可是咱們並無看到在這個組件裏調用了這個方法,因此有經驗的朋友可能會猜到這個方法是在其父組件裏經過ref
直接調用了這個addHandler
方法,代碼以下:github
class App extends Component { clickHandler = () => { this.refs.addition.addHandler(); }; render() { return ( <Provider store={store}> <div className="App"> <Addition ref='addition'/> <button onClick={this.clickHandler}>加加加</button> </div> </Provider> ); } } export default App;
這樣寫運行起來沒有任何問題:redux
經過點擊‘加加加’實現對數值的+1
處理。api
可是假若有這樣一個需求:須要在
Addition
中讀取Redux中的一個數據(固然這個例子沒有體現出來),那麼就須要connect一下了:
export default connect(mapStateToProps, mapDispatchToProps)(Addition)
嗯,看起來很完美,開開心心得從新運行下,點擊,而後....boom( ⊙ o ⊙ )啊!報錯了,app
不科學啊,說到這裏相信你們都能猜出來事connect
事後致使的問題,因此去官方文檔翻箱倒櫃一下connect([mapStateToProps], [mapDispatchToProps], [mergeProps], [options])
,
果不其然,原來connect參數有4個,因此多是遺漏了某個參數吧,因此繼續翻...
而後看到這樣一段話:框架
[withRef] (Boolean): If true, stores a ref to the wrapped component instance and makes it available via getWrappedInstance() method. Default value: false
簡單理解下,就是說connect事後export出去的不是組件自己,而是通過包裝處理的組件,官方稱之爲wrapped component
,因此默認是不將ref
存儲到這個包裝對象裏的(Default value: false
),所以只有將withRef
這個參數置爲true
,那麼Redux就會將ref
存儲到這個包裝對象裏以供使用了,而且請注意下via getWrappedInstance() method
這段話,即使咱們將withRef
置爲true
但沒有經過getWrappedInstance()
得到原對象的ref
(reference)也是不行的。因此說道這裏你們也知道解決方案是什麼了:dom
1)connect導出Addition
組件時候添加withRef
參數:
export default connect(mapStateToProps, mapDispatchToProps, null, {withRef: true})(Addition)
2)調用
addHandler
方法前使用getWrappedInstance()
得到原對象的ref
:this.refs.addition.getWrappedInstance().addHandler()
ide
而後從新運行,bingo,一切正常!!!!this
源碼 在這 ,有興趣的朋友能夠拉取代碼嘗試下。
實測,該方法在React-Native中一樣實用,這裏就不貼相關代碼了