react-native-navigation的迁移库

third-party-react-context.mdx 3.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. ---
  2. id: third-party-react-context
  3. title: React Context API
  4. sidebar_label: React Context API
  5. ---
  6. ## React Context API
  7. React Context API provides a easy way to pass data through the component tree without having to pass props down
  8. manually at every level. You can find more about the Context API in [React documentation](https://reactjs.org/docs/context.html).
  9. You can use the React Context API with React Native Navigation with a limitation. In this example, we are going to create a screen which uses the Counter Context.
  10. :::important Limitation
  11. As RNN screens are not part of the same component tree, updating the values in the shared context does not trigger a re-render across all screens.
  12. However you can still use the React.Context per RNN screen component tree.
  13. If you need to trigger a re-render across all screens, there are many popular third party libraries such as
  14. [MobX](third-party-mobx.mdx) or Redux.
  15. :::
  16. ## Create a Counter context
  17. ```tsx
  18. // CounterContext.js
  19. import React from 'react
  20. // Declaring the state object globally.
  21. const initialCounterState = {
  22. count: 0
  23. }
  24. const counterContextWrapper = (component) => ({
  25. ...initialCounterState,
  26. increment: () => {
  27. initialCounterState.count += 1
  28. component.setState({ context: contextWrapper(component) })
  29. },
  30. decrement: () => {
  31. initialCounterState.count -= 1
  32. component.setState({ context: contextWrapper(component) })
  33. },
  34. })
  35. export const CounterContext = React.createContext({})
  36. export class CounterContextProvider extends React.Component {
  37. state = {
  38. context: counterContextWrapper(this)
  39. }
  40. render() {
  41. return (
  42. <CounterContext.Provider value={this.state.context}>
  43. {this.props.children}
  44. </CounterContext.Provider>
  45. )
  46. }
  47. }
  48. ```
  49. ## Register the screen
  50. When registering the screen that will be using the Counter Context, we need to wrap it
  51. with the Counter Context Provider we created earlier.
  52. ```tsx
  53. // index.js
  54. import { Navigation } from 'react-native-navigation
  55. import { CounterContextProvider } from './CounterContext
  56. import { App } from './App
  57. Navigation.registerComponent(
  58. 'App',
  59. () => props => (
  60. <CounterContextProvider>
  61. <App {...props} />
  62. </CounterContextProvider>
  63. ),
  64. () => App
  65. )
  66. ```
  67. ## Consuming the context
  68. You can consume the Counter Context any way you want such as `Provider.Consumer` or `React.useContext` like in the
  69. example below.
  70. ```tsx
  71. // App.js
  72. import React from 'react'
  73. import { Button, Text, View } from 'react-native'
  74. import { CounterContext } from './CounterContext'
  75. export const App = () => {
  76. // Using useContext API
  77. const { count, increment, decrement } = React.useContext(CounterContext)
  78. return (
  79. <View>
  80. <Text>{`Clicked ${count} times!`}</Text>
  81. <Button title="Increment" onPress={increment} />
  82. <Button title="Decrement" onPress={decrement} />
  83. </View>
  84. )
  85. // Using Context consumer
  86. return (
  87. <CounterContext.Consumer>
  88. {({ count, increment, decrement }) => (
  89. <View>
  90. <Text>{`Clicked ${count} times!`}</Text>
  91. <Button title="Increment" onPress={increment} />
  92. <Button title="Decrement" onPress={decrement} />
  93. </View>
  94. )}
  95. </CounterContext.Consumer>
  96. )
  97. }
  98. ```