title: React

Taro supports development with React, but it is slightly different from using React in the browser, in the following ways:

Entry Component

Every Taro application needs an entry component to register the application. The default entry file is app.js in the src directory.

To use React in Taro, the entry component must export a React component. In the entry component we can set the global state or access the lifecycle of the mini-program entry instance

```jsx title=”app.js” import React, { Component } from ‘react’

// If we use the Redux import { Provider } from ‘react-redux’ import configStore from ‘./store’

// Global Style import ‘./app.css’

const store = configStore()

class App extends Component { // All React component methods can be used componentDidMount () {}

// onLaunch onLaunch () {}

// onShow componentDidShow () {}

// onHide componentDidHide () {}

render () { // Nothing will be rendered in the entry component, but we can do something like state management here return ( / this.props.children is the page that will be rendered / {this.props.children} ) } }

export default App

  1. ### onLaunch (options)
  2. > `onLaunch` of the corresponding app in the mini-program.
  3. Program initialization parameters can be accessed during this lifecycle by accessing the `options` parameter or by calling `getCurrentInstance().router`.
  4. #### Parameters
  5. ##### options
  6. | Proerty | Type | Description |
  7. | - | - | - |
  8. | path | string | Path for launch mini-program |
  9. | scene | number | Scene values for launch mini-program |
  10. | query | Object | Parameters for launch mini-program |
  11. | shareTicket | string | shareTicketSee Get More Forwarding Information |
  12. | referrerInfo | Object | Source information. Source information. Returned when accessing an mini-program from another mini-program, public number or app. Otherwise returns {} |
  13. ##### options.referrerInfo
  14. | Proerty | Type | Description |
  15. | - | - | - |
  16. | appId | string | Source mini-program, or public number (in WeChat)) |
  17. | extraData | Object | The data passed from the source mini-program is supported by WeChat and Baidu smart-program at scene=1037 or 1038 |
  18. | sourceServiceId | string | Source plugin, visible when in plugin run mode |
  19. > The options parameter may vary from field to field in different mini-program
  20. >
  21. > Scenario values , there are differences in WeChat Mini-program and Baidu Smart-program, please refer to them respectively [Wechat Mini-program](https://developers.weixin.qq.com/miniprogram/dev/framework/app-service/scene.html) 和 [Baidu Smart-program Documents](https://smartprogram.baidu.com/docs/data/scene/)
  22. ### componentDidShow (options)
  23. Triggered when the program is started, or foregrounded.
  24. As with the `onLaunch` lifecycle, program initialization parameters can be accessed during this lifecycle by accessing the `options` parameter or calling `getCurrentInstance().router`.
  25. The parameters are basically the same as those obtained in `onLaunch`, but with two additional parameters in **Baidu Smart-program** as follows.
  26. | Proerty | Type | Description |
  27. | - | - | - |
  28. | entryType | string | Source identifier, take the value of user/ schema /sys :<br />userIndicates before and after passing home<br/>Switching or unlocking the screen, etc. to bring up.<br/>schemaIndicates a protocol call-up;<br />sysOther |
  29. | appURL | string | The call-up protocol at the time of the presentation, which exists only if the value of entryType is schema |
  30. ### componentDidHide ()
  31. Triggered when the program switches to the background.
  32. ### onPageNotFound (Object)
  33. Triggered when the page to be opened by the program does not exist.
  34. #### Parameters
  35. ##### Object
  36. | Proerty | Type | Description |
  37. | - | - | - |
  38. | path | string | Path to non-existent page |
  39. | query | Object | Open the query parameter of a non-existent page |
  40. | isEntryPage | boolean | Whether it is the first page of this launch |
  41. ## Page Components
  42. Every Taro application includes at least one page component, which can jump through Taro routes and also access the lifecycle of the mini-program page.
  43. ```jsx title="Class Component"
  44. import React, { Component } from 'react'
  45. import { View } from '@tarojs/components'
  46. class Index extends Component {
  47. // All React component methods can be used
  48. componentDidMount () {}
  49. // onLoad
  50. onLoad () {}
  51. // onReady
  52. onReady () {}
  53. // onShow
  54. componentDidShow () {}
  55. // onHide
  56. componentDidHide () {}
  57. // onPullDownRefresh,except for componentDidShow/componentDidHide
  58. // All page lifecycle function names correspond to mini-program
  59. onPullDownRefresh () {}
  60. render () {
  61. return (
  62. <View className='index' />
  63. )
  64. }
  65. }
  66. export default Index

```jsx title=”Functional Component” import React, { useEffect } from ‘react’ import { View } from ‘@tarojs/components’ import { useReady, useDidShow, useDidHide, usePullDownRefresh } from ‘@tarojs/taro’

function Index () { // All React Hooks can be used useEffect(() => {})

// onReady useReady(() => {})

// onShow useDidShow(() => {})

// onHide useDidHide(() => {})

// Taro implements custom React Hooks for all mini-program page lifecycles to support usePullDownRefresh(() => {})

return ( ) }

export default Index

  1. ### Routing parameters
  2. In the page component, the routing parameters for the current page can be obtained via `getCurrentInstance().router`.
  3. ```jsx
  4. import React, { Component } from 'react'
  5. import { View } from '@tarojs/components'
  6. class Index extends Component {
  7. // It is recommended that the result of getCurrentInstance() be saved for later use when the page is initialized.
  8. // instead of calling this API frequently
  9. $instance = getCurrentInstance()
  10. componentDidMount () {
  11. // Get router parameters
  12. console.log($instance.router)
  13. }
  14. render () {
  15. return (
  16. <View className='index' />
  17. )
  18. }
  19. }
  20. export default Index

Lifecycle Trigger

Taro 3 implements a web-standard BOM and DOM API on the mini-program logic layer. So the document.appendChild, document.removeChild, and other APIs used by React are actually implemented by Taro emulation, with the end effect of rendering React’s virtual DOM tree as a Web-standard DOM tree emulated by Taro.

So in Taro3, React’s lifecycle trigger timing is a little different from what we normally understand in web development.

React lifecycle

The lifecycle methods of React components are supported in Taro.

Trigger timing:

1. componentWillMount ()

After onLoad, the page component is triggered before rendering to Taro’s virtual DOM.

2. componentDidMount ()

Triggered after the page component is rendered to Taro’s virtual DOM.

Taro’s virtual DOM is accessible at this point (using methods such as React ref, document.getElementById, etc.), and modifications to it are supported (setting the style of the DOM, etc.).

However, this does not mean that Taro’s virtual DOM data has been transferred from the logical layer setData to the view layer. So at this point it is not possible to get the DOM nodes of the rendering layer of the mini program by methods like createSelectorQuery. You can only get the DOM node in onReady lifecycle.

Methods for mini-program pages

The methods in the mini-program page can also be used in Taro’s page: write the methods with the same name in the Class Component and use the corresponding Hooks in the Functional Component.

Attention:

  • Mini-program page methods also differ across platforms
  • Mini-program page components that use HOC wrappers must handle forwardRef or use inherited components instead of returned components, otherwise the mini program page method may not be triggered.

onLoad (options)

onLoad of the corresponding page in the mini-program.

Page routing parameters can be accessed during this lifecycle by accessing the options parameter or by calling getCurrentInstance().router.

onReady ()

onReady of the corresponding page in the mini-program.

This lifecycle begins with access to the DOM nodes of the mini-program rendering layer using APIs such as createCanvasContext or createSelectorQuery.

The onReady of the child component

The onReady lifecycle is only triggered for page components. Child components can use Taro’s built-in Message System to listen to the onReady() lifecycle of the page component.

```jsx title=”A child component in a page” import React from ‘react’ import { View } from ‘@tarojs/components’ import Taro, { eventCenter, getCurrentInstance } from ‘@tarojs/taro’

class Test extends React.Component { $instance = getCurrentInstance()

componentWillMount () { const onReadyEventId = this.$instance.router.onReady eventCenter.once(onReadyEventId, () => { console.log(‘onReady’)

  1. Taro.createSelectorQuery().select('#only')
  2. .boundingClientRect()
  3. .exec(res => console.log(res, 'res'))
  4. })

}

render () { return ( ) } }

  1. But when the child component is **load-on-demand**, the page `onReady` has already been triggered. If this on-demand subcomponent needs to get the DOM node of the rendering layer of the mini program because it missed the page `onReady`, it can only try to simulate it using `Taro.nextTick`.
  2. ```jsx title="Load-on-demand subcomponents"
  3. import React from 'react'
  4. import { View } from '@tarojs/components'
  5. import Taro from '@tarojs/taro'
  6. class Test extends React.Component {
  7. componentDidMount () {
  8. Taro.nextTick(() => {
  9. // Use Taro.nextTick to simulate that setData has ended and the node has finished rendering
  10. Taro.createSelectorQuery().select('#only')
  11. .boundingClientRect()
  12. .exec(res => console.log(res, 'res'))
  13. })
  14. }
  15. render () {
  16. return (
  17. <View id="only" />
  18. )
  19. }
  20. }

componentDidShow ()

onShow of the corresponding page in the mini-program.

Triggered when the page is displayed/entered in the foreground.

The onShow of the Subcomponents

The onShow lifecycle is only triggered for page components. Subcomponents can use Taro’s built-in message system to listen to the onShow() lifecycle of the page component.

```jsx title=”A sub-component of the page” import React from ‘react’ import { View } from ‘@tarojs/components’ import { eventCenter, getCurrentInstance } from ‘@tarojs/taro’

class Test extends React.Component { $instance = getCurrentInstance()

componentWillMount () { const onShowEventId = this.$instance.router.onShow eventCenter.on(onShowEventId, this.onShow) }

componentWillUnmount () { const onShowEventId = this.$instance.router.onShow eventCenter.off(onShowEventId, this.onShow) }

onShow = () => { console.log(‘onShow’) }

render () { return ( ) } }

  1. ### componentDidHide ()
  2. > `onHide` of the corresponding page in the mini-program.
  3. Triggered when the page is hidden/entered in the background.
  4. #### The onHide of a subcomponent
  5. The `onHide` lifecycle is only triggered for page components.
  6. Subcomponents can use Taro's built-in [message system]($i18n-en-docusaurus-plugin-content-docs-current-apis-about-events) to listen to the `onHide()` lifecycle of the page component.
  7. ```jsx title="A sub-component of the page"
  8. import React from 'react'
  9. import { View } from '@tarojs/components'
  10. import { eventCenter, getCurrentInstance } from '@tarojs/taro'
  11. class Test extends React.Component {
  12. $instance = getCurrentInstance()
  13. componentWillMount () {
  14. const onHideEventId = this.$instance.router.onHide
  15. eventCenter.on(onHideEventId, this.onHide)
  16. }
  17. componentWillUnmount () {
  18. const onHideEventId = this.$instance.router.onHide
  19. eventCenter.off(onHideEventId, this.onHide)
  20. }
  21. onHide = () => {
  22. console.log('onHide')
  23. }
  24. render () {
  25. return (
  26. <View id="only" />
  27. )
  28. }
  29. }

onPullDownRefresh ()

Listen to the user drop-down action.

  • You need to set it in the window option of the global configuration or in the page configuration enablePullDownRefresh: true.
  • The pull-down refresh can be triggered by Taro.startPullDownRefresh, which triggers the pull-down refresh animation after the call, and the effect is the same as the user’s manual pull-down refresh.
  • When the data has been processed and refreshed, Taro.stopPullDownRefresh You can stop the drop-down refresh of the current page.

onReachBottom ()

Listen to the user pull-up bottoming event.

  • The trigger distance can be set in the window option of the global configuration or in the page configuration onReachBottomDistance
  • This event will only be triggered once during the slide within the trigger distance

H5 does not have synchronization for now, you can simulate it by binding scroll events to window

onPageScroll (Object)

Listening to user swipe page events

H5 does not have synchronization for now, you can simulate it by binding scroll events to window

Parameters

Object
Parameters Type Description
scrollTop Number The distance the page has scrolled in the vertical direction (unit: px)

onAddToFavorites (Object)

Listen to the user’s click on the “Favorites” button in the upper-right corner of the menu and customize the contents of the favorites.

Supported by Taro 3.0.3 and above. Only supported by WeChat mini-program , this interface is Beta version, supported from Android version 7.0.15, only supported in Android platform for now.

Parameters

Object
Parameters Type Description
webviewUrl String If the page contains a web-view component, the url of the current web-view is returned

This event handler requires the return of an Object, which is used to customize the contents of the collection.

Fields Description Default
title Customized Title Page title or account name
imageUrl Customize the image, displaying it with an aspect ratio of 1:1 Page Screenshot
query Custom query fields Current page query

Sample Code

```js title=”page.js” onAddToFavorites (res) { // webview page return webviewUrl console.log(‘WebviewUrl: ‘, res.webviewUrl) return { title: ‘custom title’, imageUrl: ‘https://demo.png‘, query: ‘name=xxx&age=xxx’, } }

  1. ### onShareAppMessage (Object)
  2. Listen to the user's behavior when they click on the forward button (Button component openType='share') or the "Forward" button in the top-right menu, and customize the forwarding content.
  3. **Attention:**
  4. 1. When `onShareAppMessage` is not triggered, please set `enableShareAppMessage: true` in the page config
  5. 2. Only if this event handler is defined, the "Forward" button will be displayed in the upper right menu
  6. #### Parameters
  7. ##### Object
  8. | Parameters | Type | Description |
  9. | - | - | - |
  10. | from | String | Forwarding event sources <br />button: In-page forwarding buttons. <br />menu: Top right corner forwarding menu |
  11. | target | Object | If the `from` value is `button`, then `target` is the `button` that triggered the forwarding event, otherwise it is `undefined` |
  12. | webViewUrl | String | Returns the url of the current `WebView` if the page contains a `WebView` component |
  13. This event requires the return of an Object, which is used to customize the forwarding content, and returns the following:
  14. Custom forwarding content
  15. | Fields | Type | Description |
  16. | - | - | - |
  17. | title | Forwarding Title | Current mini-program name |
  18. | path | Forwarding Title | Current page path, must be a full path starting with / |
  19. | imageUrl | Custom image path, either local file path, package file path or network image path. Support PNG and JPG. Display image aspect ratio is 5:4 | Use default screenshot |
  20. #### Sample Code
  21. ```jsx title="page.js"
  22. export default class Index extends Component {
  23. onShareAppMessage (res) {
  24. if (res.from === 'button') {
  25. // From the on-page forward button
  26. console.log(res.target)
  27. }
  28. return {
  29. title: 'Custom forwarding title',
  30. path: '/page/user?id=123'
  31. }
  32. }
  33. }

``jsx title="page.config.js" export default { // WhenonShareAppMessage` is not triggered, you can try to configure this option enableShareAppMessage: true }

  1. ### onShareTimeline ()
  2. Listen to the behavior of the "Share to moments" button in the top-right menu and customize the sharing content.
  3. > Taro version 3.0.3 and above support
  4. > Only WeChat mini-program are supported, the base library 2.11.3 starts to support, this interface is a Beta version, only supported in Android platform for now
  5. **Attention:**
  6. 1. When `onShareAppMessage` is not triggered, please set `enableShareAppMessage: true` in the page config
  7. 2. Only if this event handler is defined, the "Forward" button will be displayed in the upper right menu
  8. #### Return Values
  9. The event handler function can return an Object for customizing the shared content, does not support custom page paths, and returns the following content.
  10. | Fields | Description | Defalut |
  11. | - | - | - |
  12. | title | Custom title | Current mini-program name |
  13. | query | The parameters carried in the custom page path | The parameters carried in the current page path |
  14. | imageUrl | Custom image path, can be local file or network image. Support PNG and JPG, display image aspect ratio is 1:1. | default use mini-program Logo |
  15. ```jsx title="page.js"
  16. class Index extends Component {
  17. onShareTimeline () {
  18. console.log('onShareTimeline')
  19. return {}
  20. }
  21. }

```jsx title=”page.config.js” export default { enableShareTimeline: true }

  1. ### onResize (Object)
  2. Triggered when the mini-program screen is rotated. For details, see [Response to display area changes](https://developers.weixin.qq.com/miniprogram/dev/framework/view/resizable.html#%E5%9C%A8%E6%89%8B%E6%9C%BA%E4%B8%8A%E5%90%AF%E7%94%A8%E5%B1%8F%E5%B9%95%E6%97%8B%E8%BD%AC%E6%94%AF%E6%8C%81)。
  3. ### onTabItemTap (Object)
  4. Triggered when the tab is clicked.
  5. #### Parameters
  6. ##### Object
  7. | Parameters | Type | Description |
  8. | - | - | - |
  9. | index | String | The serial number of the clicked tabItem, starting from 0 |
  10. | pagePath | String | The path to the page where the tabItem was clicked |
  11. | text | String | The text of the clicked tabItem's button |
  12. ### onTitleClick ()
  13. > Only Alipay Mini-program support
  14. Click on the title to trigger
  15. ### onOptionMenuClick ()
  16. > Only Alipay Mini-program support
  17. Triggered by clicking on additional icons in the navigation bar
  18. ### onPopMenuClick ()
  19. > Only Alipay Mini-program support
  20. No description yet
  21. ### onPullIntercept ()
  22. > Only Alipay Mini-program support
  23. Triggered on dropdown truncation
  24. ## Built-in components
  25. Taro is developed using built-in components of the mini-program specification, such as `<View />`, `<Text />`, `<Button />`, etc.
  26. Before using these built-in components in React, they must be brought in from `@tarojs/components` and the component props follow the **Upper camelcase naming convention**.
  27. Mini-program writing method:
  28. ```html
  29. <view hover-class='test' />

Taro writing method:

  1. import { View } from '@tarojs/components'
  2. <View hoverClass='test' />

Events

Events in Taro follow the lower camelcase naming convention, with all built-in event names starting with on.

In the event callback function, the first argument is the event itself, and calling stopPropagation in the callback will stop the bubbling.

  1. function Comp () {
  2. function clickHandler (e) {
  3. e.stopPropagation()
  4. }
  5. function scrollHandler () {}
  6. // The mini-program bindtap corresponds to Taro's onClick
  7. // The rest of the mini-program event names replace bind with on, which is the name of the Taro event (except for the Alipay mini-program, whose event starts with on)
  8. return <ScrollView onClick={clickHandler} onScroll={scrollHandler} />
  9. }

Taro 3 event system on the mini-program

In Taro 1 & 2, Taro determines whether the events bound in the mini program template are in the form of bind or catch depending on whether the developer uses e.stopPropagation(). Thus event bubbling is controlled by the mini-program.

But in Taro 3, we have implemented a system of events in the mini-program logic layer, including event triggering and event bubbling. The events bound in the mini-program template are in the form of bind.

In general, this system of mini-program events implemented in the logic layer works properly, with event callbacks that trigger, bubble, and stop bubbling correctly.

However, the catchtouchmove event bound to the mini-program template prevents the callback function from bubbling through in addition to preventing the view from scrolling through**, something Taro’s event system cannot do.

Block rolling penetration

In the previous point, we introduced the event mechanism of Taro 3. Since events are bound as bind, you cannot use e.stopPropagation() to prevent scroll-through.

Two solutions are summarized for the problem of rolling penetration:

一、Style

Use the style to solve. Disable scrolling of penetrated components

This is also the most recommended practice.

二、CatchMove

Supported by Taro 3.0.21 and above

But the map component itself is scrollable, even if its width and height are fixed. So the first approach can’t handle the scrolling events that bubble up to the map component.

This is the time to add the catchMove property to the View component.

  1. // This View component will bind the catchtouchmove event instead of bindtouchmove.
  2. <View catchMove></View>

Global Variables

When using React, global variables are recommended to be managed using a state management tool such as React Redux.

And sometimes some projects converting from native mini-program mount global variables to app and use getApp() to get them. Converting to the React ecosystem’s way of managing state is more costly.

Therefore, you can use the taroGlobalData property of the entry object for compatibility with this writing style.

```jsx title=”app.js” class App extends Component { taroGlobalData = { x: 1 } render () { return this.props.children } }

  1. ```jsx title="index.js"
  2. function Index () {
  3. const app = Taro.getApp()
  4. console.log(app.x)
  5. return (...)
  6. }

Hooks

Hooks Document

Other limitations

  • Since mini-program do not support dynamic introduction, the React.lazy API cannot be used in mini-program.
  • It is not possible to insert elements outside the DOM tree of a page component, so <Portal> is not supported.
  • The id of all components must remain unique throughout the application (even if they are on different pages), otherwise it may cause problems with events not firing.#7317

Frequently Asked Questions

  • The render layer element information is not available in useEffect, componentDidMount.7116
  • The latest width and height of the component is not available in useEffect or useLayoutEffect.#7491
  • When the nesting level is deep, the child elements cannot be queried using selectorQuery.#7411