Home > Blockchain >  Unable to access props during React.cloneElement after upgrade to 17.0.2
Unable to access props during React.cloneElement after upgrade to 17.0.2

Time:10-11

I use React.cloneElement to override the default styles fr Text in react-native. Below is my implementation:

const React = require('react')
const { Platform, Text } = require('react-native')
const colorThemes = require('galarm-config').colorThemes

const defaultFontProperties = {
  ...Platform.select({
    android: {
      fontFamily: 'Roboto',
      fontSize: 16
    },
    ios: { fontSize: 16 }
  })
}

const oldRender = Text.render
if (oldRender) {
  Text.render = function (...args) {
    const origin = oldRender.call(this, ...args)
    const colorScheme = origin.props.colorScheme
    console.tron.log('text color scheme', colorScheme, origin.props.children)
    return React.cloneElement(origin, {
      style: [
        defaultFontProperties,
        { color: colorThemes.getColorTheme(colorScheme).textColor },
        origin.props.style
      ]
    })
  }
}

I have been using it successfully for quite some time. I recently updated to react-native 0.66 after which the below code stopped working. The issue is that the colorScheme prop is read as undefined on line 19.

Below is how the colorScheme is set

<Text colorScheme={'dark'}>
  {'Some text'}
</Text>

I am not sure if something has changed in react 17.0.2 which causes the colorScheme prop to be not set. I have run it in debugger and of course the colorScheme prop is not set but I don't know how to debug this further.

Any help is appreciated.

CodePudding user response:

Something should have changed in react/react-native internals that filters out custom props in the rendered node(origin). However, you can still access all the props you pass via the args since the first one corresponds to the props. You can do this instead

    const props = args[0];
    const colorScheme = props.colorScheme;

CodePudding user response:

If, by colorScheme you mean (dark/light) mode, you can grab it directly from the appearance module:

import {Appearance } from 'react-native';
const theme = Appearance.getColorScheme();

so your code should work like this:

    const React = require('react')
    const { Platform, Text, Appearance } = require('react-native')
    const colorThemes = require('galarm-config').colorThemes


    const defaultFontProperties = {
    ...Platform.select({
        android: {
        fontFamily: 'Roboto',
        fontSize: 16
        },
        ios: { fontSize: 16 }
    })
    }

    const oldRender = Text.render
    if (oldRender) {
    Text.render = function (...args) {
        const origin = oldRender.call(this, ...args)
        const colorScheme = Appearance.getColorScheme(); // either 'light' or 'dark'
        console.tron.log('text color scheme', colorScheme, origin.props.children)
        return React.cloneElement(origin, {
        style: [
            defaultFontProperties,
            { color: colorThemes.getColorTheme(colorScheme).textColor },
            origin.props.style
        ]
        })
    }
    }

otherwise i don't know

  • Related