相信用过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中一样实用,这里就不贴相关代码了