【问题标题】:Access an object property dynamically using a variable's value ReactNative+Typescript使用变量的值 ReactNative+Typescript 动态访问对象属性
【发布时间】:2021-11-20 13:45:41
【问题描述】:

所以我试图通过让从样式表中选择的样式取决于通过属性传入的字符串来使该组件具有动态分配的样式

export type MyComponentProps = {
  styleName: string;
}

const MyComponent = (props: MyComponentProps) => {
  const { styleName } = props;
  
  return (
    <View
      style={[
        styles['container'],
        styles[`view${styleName}`],
      ]}>
      <Text
        style={[
          styles['text'],
          styles[`text${styleName}`],
        ]}>
        Hello World
      </Text>
    </View>
  );
}


const styles = StyleSheet.create({
  container: {
    width: '100%',
    alignItems: 'center',
  },

  viewDark: {
    backgroundColor: 'black',
  },

  viewLight: {
    borderColor: 'white',
  },

  text: {
    fontWeight: 'bold',
  },

  textDark: {
    color: 'white',
  },

  textLight: {
    color: 'black',
  },
}

但这会引发错误

元素隐式具有“任何”类型,因为“视图${any}”类型的表达式不能用于索引类型“{容器:{宽度:字符串;对齐项目:“中心”; }; viewDark:{背景颜色:字符串; }; viewLight:{背景颜色:字符串; };文本: { ...; };文本黑暗:{ ...; };文本灯:{ ...; }; }'。

我试图避免任何样式本身通过道具进入,我看到这是很多推荐的东西

我也知道看到styles['container']而不是styles.container可能会伤害你的眼睛,但我只是想尽可能清楚地说明我的目标是什么,所以让${styleName}成为这两种情况之间的唯一区别会有所帮助

【问题讨论】:

    标签: typescript react-native


    【解决方案1】:

    所以经过一些研究,只要我们将动态创建的字符串转换为我们赋予样式变量的任何接口的键,我们就可以轻松地做到这一点。 所以在这种情况下,这可以通过

    来完成
    export type MyComponentProps = {
      styleName: string;
    }
    
    const MyComponent = (props: MyComponentProps) => {
      const { styleName } = props;
      
      return (
        <View
          style={[
            styles['container'],
            styles[`view${styleName}` as keyof IStyles],
          ]}>
          <Text
            style={[
              styles['text'],
              styles[`text${styleName}` as keyof IStyles],
            ]}>
            Hello World
          </Text>
        </View>
      );
    }
    
    interface IStyles {
      container: object,
      viewDark: object,
      viewLight: object,
      text: object,
      textDark: object,
      textLight: object,
    }
    
    const styles: IStyles = StyleSheet.create({
      container: {
        width: '100%',
        alignItems: 'center',
      },
    
      viewDark: {
        backgroundColor: 'black',
      },
    
      viewLight: {
        borderColor: 'white',
      },
    
      text: {
        fontWeight: 'bold',
      },
    
      textDark: {
        color: 'white',
      },
    
      textLight: {
        color: 'black',
      },
    }
    

    不要忘记将样式声明为具有接口 IStyles const styles: IStyles = ...

    【讨论】:

      【解决方案2】:

      因此,在某些情况下,其他解决方案似乎不起作用,但我仍然会保留它,以便读者可以了解任何选项。 这个无论如何都没有失败,我们不需要创建一个接口,所以这也可能是一个加号

      export type MyComponentProps = {
        styleName: string;
      }
      
      const MyComponent = (props: MyComponentProps) => {
        const { styleName } = props;
      
        const viewStyle = `view${styleName}`; // Possibly more readable
        
        return (
          <View
            style={[
              styles['container'],
              `view${styleName}` == 'viewDark'
                ? styles['viewDark']
                : {},
              viewStyle == 'viewLight' // Using the more readable alternative
                ? styles['viewLight']
                : {},
            ]}>
            <Text
              style={[
                styles['text'],
                `text${styleName}` == 'textDark'
                ? styles['textDark']
                : {},
                `text${styleName}` == 'textLight'
                ? styles['textLight']
                : {},
              ]}>
              Hello World
            </Text>
          </View>
        );
      }
      
      const styles = StyleSheet.create({
        container: {
          width: '100%',
          alignItems: 'center',
        },
      
        viewDark: {
          backgroundColor: 'black',
        },
      
        viewLight: {
          borderColor: 'white',
        },
      
        text: {
          fontWeight: 'bold',
        },
      
        textDark: {
          color: 'white',
        },
      
        textLight: {
          color: 'black',
        },
      }
      

      缺点是我们必须手动编写 if 语句来检查它是否分别等于每种可能的样式,但优点是它看起来更可靠

      【讨论】:

        猜你喜欢
        • 2021-10-25
        相关资源
        最近更新 更多