浅谈ReactNative传参的⼏种⽅式(⼩结)
在React Native 中由于业务的需要, 我们往往要在诸多的页⾯间,组件之间做⼀些参数的传递与管理, 在这⾥我总结了⼏⼤经过验证,稳定好⽤的⽅式给⼤家
React Navigation 导航传值
推荐指数: ♥♥♥♥♥
适⽤范围: 相互跳转的页⾯间传值
兼容性: IOS/Android
原理: React Navigation 为页⾯的 props 上挂载了 navigation 对象, 可⽤来做路由跳转,在做页⾯跳转时可以携带参数/回调⽅法前往⽬标页⾯,从⽽达到传参的⽬的
说明: 这是官⽅推荐,也是我们在业务开发中⽤得最多,最为推崇的⼀种传参⽅式, 思想与 web 在 querystring 上带参跳转类似,只是实现⽅式略微不同, 举例
导航传值即可正向传值,也可反向传值例如 A->B 是正向传值,⽽B->A 则是反向传值
正向传值:
A页⾯跳转向B页⾯, 在组件内通过访问 this.props.navigation.navigate('B', {
type: 'list',
callback:data => { console.log('data in callback: ', data); }
});
在B页⾯就能在组件的⽣命周期函数中拿到值
componentWillMount() {
const { state: { params: { type, callback }, goBack }} = this.props.navigation;
console.log('type: ', type);
// type 'list'
}
reactnative开发
反向传值:在反回上⼀个页⾯时, ⼿动调⽤callback,并给其传参, 再调⽤ goBack ⽅法,即可达到⽬的
还是上⾯的例⼦:
当从B返回A的时候
goBackToPageA: () => {
const { state: { params: { type, callback }, goBack }} = this.props.navigation;
callback({ id: '123', message: type + ' really?'});
goBack();
}
goBackToPageA();
回到A页⾯后
'data in callback: ', { id: '123', message: 'list really?'});
也即callBack 中的 data 参数就是 { id: '123', message: 'list really?'}
DeviceEventEmitter 触发事件并传值
推荐指数: ♥♥♥♥
适⽤范围: 页⾯间传值/组件间传值
兼容性: IOS/Android
原理: 利⽤ React Native 包中提供的 DeviceEventEmitter 模块订阅事件,触发事件,并能同时传值
说明: DeviceEventEmitter 从名字就能知道他是基于事件订阅的机制来进⾏传值的, 当订阅某种事件后,触发的时候会调⽤订阅事件的回调, 并能把值传送过去, 并且在同页⾯内的组间件,不同页⾯间都可以传值, 但前提是页⾯还未被销毁(销毁后事件的订阅会取消), 例如:
DeviceEventEmitter.addListener('warning_event', (data) => { console.log('data: ', data);})
// data: { name: 'Mega Galaxy' }
在emit(触发)事件后, 回调函数的⼊参就变成了我们所传递的 { name: 'Mega Galaxy'},
也可不传值,不传值时 callback 的⼊参就是 undefined
缺点: 本质是对⾃定义事件的监听与触发,当页⾯逻辑复杂时,代码会相对变⼤,维护成本变⾼,且监听过多会造成性能问题,还有⼀点就是在页⾯销毁时必须移除监听: 如果忘记移除监听会怎么样? 那emit ⼀次的时候,会多响应⼀次你加上去的监听
componentDidMount() {
this.eventHandler = DeviceEventEmitter.addListner('event_name', callback);
}
componentWillUnmount() {
ve();
}
个⼈建议: 在梳理清楚页⾯逻辑后,合理使⽤
AsyncStorage Key-Value 式的存储传参
推荐指数: ♥♥♥♥
适⽤范围: 跨页⾯跨组件的任性传参
兼容性: IOS/Android
原理: 利⽤类似 web 中 localStorage 的思想,将参数/数据存放在 AsyncStorage中,在需要的地⽅再取出来
说明: localStorage 在 web 中的实⽤性与受欢迎程度⼤家是知道的, AsyncStorage其实就是 rn 版的 localStorage, 略微不同的是它是异步的,只返回 Promise, 所以与 async/await 结合会⾮常好⽤
···
在A页⾯
saveOrderData = async () => {
try {
const orderData = [{ id: 1, data: []}, { id: 2, data: []}]
await AsyncStorage.setItem('Order_data_cache', JSON.stringify(orderData ));
} catch (error) {
// Error saving data
}
}
在B页⾯
loadOrderData = async () => {
const __orderData = Item('Order_data_cache');
const orderData = JSON.parse(__orderData);
this.setState({ orderData });
}
缺点: 以 Key-Value 式的存储传参,可能重点还是在数据存储上, 且因为涉及到 I/O 的操作,在部份低端机型上,有卡顿的可能性
React Context Api 传参(新版Context Api)
推荐指数: ♥♥♥
适⽤范围: 不同页⾯间的组件共享公共类的数据
兼容性: IOS/Android
原理: 利⽤⽣成的数据仓库包裹⽗级组件, 再从⼦组件中获取数据仓库中的数据
说明: Context Api 在管理登录⽤户数据这类具有公共属性的数据是⼀把利器,但使⽤起来会相当繁琐
const ContextWrapper = ateContext();
<ContextWrapper.Provider value={{ name: 'Mega Galaxy', job: 'FrontEnd Engineer' }}
<App />
<ContextWrapper.Provider>
// 注意这⾥的 <App /> 是指我们 App的根组件,在包裹根组件后我们可以在任意⼦页⾯组件中取值
任意 <App /> ⾥的⼦页⾯组件中
<ContextWrapper.Counsumer>
{ context => <Text> { context.name } { context.job }</Text> }
</ContextWrapper.Counsumer>
会渲染成 <Text> Mega Galaxy FrontEnd Engineer </Text>
缺点: 理解需要花⼀些功夫, 写法繁琐,且只适合特定类型的数据,要明确组件间的包裹关系
Global 传值
推荐指数: ♥♥♥
适⽤范围: 页⾯间传值
兼容性: IOS/Android
原理: 利⽤ Node.js 中的顶级对象 Global 来挂载属性, 利⽤属性传值
说明: 在跳转的页⾯前,可以把需要传递的参数挂载在 Global 对象上, 在跳转后即可在 Global 对象上取过相同的键取到对应的值, 例如: 在 A 页⾯跳转 B 页⾯时, Global.params = { name: 'Jalon', id: '123456'}, 在跳转之后, 即可通过 Global.params 拿到值,除了普通的字值串,布尔值,对象,数组, 也可以传递函数, 但要注意带有 this.setState ⽅法的函数传递后调⽤可能会报错.
缺点: 如果挂载的属性/⽅法过多易造成冲突与污染, 不利于维护
个⼈建议: 在 react-navigation 跳转传值与 DeviceEventEmitter 维护不⽅便的情况下才使⽤, 但尽量少⽤, 以免造成 Global 属性的污染与冲突
总结了5种常见的参数/数据传递的⽅法,以个⼈⾓度来看,推荐顺序为 React Navigation 导航传值 > DeviceEventEmitter 触发事件并传值 > AsyncStorage Key-Value 式的存储传参, 最后两种是在特殊场景下才会去使⽤,所以朋友们,在合适的场景选择合适的⽅式去传值,会为React Native项⽬的开发带来更为理想的效果,感谢您的阅读,也希望⼤家多多⽀持。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。