最难看公司代码和redux官方文时了解到monkey patch这个名词的。monkey是猴子的意思,patch是补丁的意思,monkey patch的意思就是你先去抓一只猴子,然后给他们线和针,教他们打补丁,等他们学会了之后就可以自己给自己打补丁了——开个玩笑。Wikipedia上对monkey patch的定义是:
A monkey patch is a way for a program to extend or modify supporting system software locally (affecting only the running instance of the program).
大家在写react native的时候应该会写过类似下面的代码:
import { Stylesheet } from 'react-native' const styles = StyleSheet.create({ swiperSlideDot: { borderRadius: 3 } })
这段代码其实没啥好看的-_-。不过有时候,你可能会根据当前平台是iOS还是android来写一些不一样的样式,然后你可能会写出类似下面这样的代码:
import { StyleSheet, Platform } from 'react-native' const styles = StyleSheet.create({ swiperSlideDot: { borderRadius: Platform.OS === 'ios' ? 3 : 4 } })
但是有些场景下你可能会想要这么写(请注意,这是一段错误的代码):
// 请注意,这是一段错误的代码 import { StyleSheet } from 'react-native' const styles = StyleSheet.create({ swiperSlideDot: { ios: { borderRadius: 3, }, android: { borderRadius: 4 } } })
上面这段代码直接跑是会出问题的,因为Stylesheet.create方法的入参对象里面只能包含一层对象,是不允许嵌套第二层对象的。这个时候,我们就可以使用Monkey patch技术了。
1、先编写一个Stylesheet.js文件:
// Stylesheet.js import { StyleSheet, Platform } from 'react-native' function create (styles) { function styleFor (name) { const { ios, android, ...style } = { ...styles[name] } if (ios && Platform.OS === 'ios') { return { ...style, ...ios } } else if (android && Platform.OS === 'android') { return { ...style, ...android } } return style } const result = Object.keys(styles).map(key => ({ [key]: styleFor(key) })) .reduce((loop, next) => ({ ...loop, ...next, }), {}) return StyleSheet.create(result) } export default { ...StyleSheet, create, }
2、然后就可以上之前那样写代码了:
// 注意,这里不是import { StyleSheet } from 'react-native' import { StyleSheet } from './StyleSheet' const styles = StyleSheet.create({ swiperSlideDot: { ios: { borderRadius: 3, }, android: { borderRadius: 4 } } })
你看,其实我们并没有修改React Native提供的Stylesheet.create方法,我们只是另外又暴露了一个Stylesheet.create方法,用起来就跟用React Native的Stylesheet方法一样,只是略微增加了一些定制功能。
redux的middleware中间件的实现原理也是monkey patch,具体就不在赘述了,官网上已经写得很明白了(每应用一个中间件,就相当于原先的store.dispatch方法(指的是上一个中间件修改后的store.dispatch方法,只有在未应用任何中间件的情况下才是redux提供的store.dispatch方法)的基础上暴露了新的store.dispatch方法):http://redux.js.org/docs/advanced/Middleware.html。
参考:
- http://redux.js.org/docs/advanced/Middleware.html