React Native:require() 与动态字符串?

IT技术 javascript reactjs react-native ecmascript-6 require
2021-01-30 15:52:18

我已经阅读了几篇关于人们require()在尝试需要动态资源时遇到的 React Native 和函数问题的帖子,例如:

动态(失败)

urlName = "sampleData.json";
data = require('../' + urlName);

与静态(成功)

data = require('../sampleData.json');

我在一些线程中读到这是 React Native 中的一个错误,而在其他线程中则认为这是一个特性。

是否有一种新方法可以在函数中使用动态资源?

相关帖子(在 React 时间都相当老):

6个回答

正如我所听到的,react的require()只使用静态URL不变量,这意味着你必须做的require('/path/file'),看看这个GitHub上的问题这一个更多的替代解决方案,也有一些其他的方式来做到这一点!例如

const images = {
profile: {
    profile: require('./profile/profile.png'),
    comments: require('./profile/comments.png'),
},
   image1: require('./image1.jpg'),
   image2: require('./image2.jpg'),
};

export default images;

然后

import Images from './img/index';

render() {
    <Image source={Images.profile.comments} />
}

从这个答案

好吧,这太糟糕了,我想从 firebase 检索图像源,但我不能动态地进行。所以现在我必须使用云存储,并提供全面的离线支持
2021-03-21 15:52:18
@metalheadcoder 没有办法解决它,我只是为他们创建了一个大的 json 文件
2021-03-25 15:52:18
嘿@MartínSchere 除了使用云存储之外,您还有其他选择吗?现在我面临和你一样的问题,使用导入图像一个一个的解决方案对我来说是多余的..
2021-03-31 15:52:18

这是我的解决方案。

设置

文件结构:

app  
  |--src
    |--assets
      |--images
        |--logos
          |--small_kl_logo.png
          |--small_a1_logo.png
          |--small_kc_logo.png
          |--small_nv_logo.png
          |--small_other_logo.png

        |--index.js
    |--SearchableList.js

index.js,我有这个:

const images = {
  logos: {
    kl: require('./logos/small_kl_logo.png'),
    a1: require('./logos/small_a1_logo.png'),
    kc: require('./logos/small_kc_logo.png'),
    nv: require('./logos/small_nv_logo.png'),
    other: require('./logos/small_other_logo.png'),
  }
};

export default images;

在我的SearchableList.js组件中,我然后像这样导入了 Images 组件:

import Images from './assets/images';

然后imageSelect我在我的组件中创建了一个新函数

imageSelect = network => {
  if (network === null) {
    return Images.logos.other;
  }

  const networkArray = {
    'KL': Images.logos.kl,
    'A1': Images.logos.a1,
    'KC': Images.logos.kc,
    'NV': Images.logos.nv,
    'Other': Images.logos.other,
  };

  return networkArray[network];
};

然后在我的组件render函数中,我调用这个新imageSelect函数来根据 中的值动态分配所需的图像this.state.network

render() {
  <Image source={this.imageSelect(this.state.network)} />
}

传递给 imageSelect 函数的值可以是任何动态字符串。我只是选择先将它设置在 state 中,然后传入。

我希望这个答案有帮助。:)

谢谢!这是多个图像的最佳方法。就我而言,我还必须在 'require("..")' 的末尾添加 '.default'。
2021-04-08 15:52:18

对于无法使用现有答案的阅读本文的任何人,我有一个选择。

首先,我将解释我的场景。我们有一个包含许多包的单一仓库(大型 react-native 应用程序)。我想为 i18n 动态导入一堆语言环境文件,而不必在某些魔术文件中保留中央注册表。可能有多个团队在同一个 monorepo 中工作,我们想要的 DX 是让包开发人员能够将他们的本地文件添加到已知文件夹中,{{packageName}}/locales/en.json并让我们的核心 i18n 功能获取他们的字符串。

经过几个不太理想的解决方案,我终于登陆https://github.com/kentcdodds/babel-plugin-preval作为我们的理想解决方案。我是这样做的:

const packageEnFiles = preval`
  const fs = require('fs');
  const path = require('path');

  const paths = [];

  const pathToPackages = path.join(__dirname, '../../../../packages/');
fs.readdirSync(pathToPackages)
    .filter(name => fs.lstatSync(path.join(pathToPackages, name)).isDirectory())
    .forEach(dir => {
      if (fs.readdirSync(path.join(pathToPackages, dir)).find(name => name === 'locales')) {
        const rawContents = fs.readFileSync(path.join(pathToPackages, dir, 'locales/en.json'), 'utf8');
        paths.push({
          name: dir,
          contents: JSON.parse(rawContents),
        });
      }
    });

  module.exports = paths;
`;

然后我可以遍历这个列表并将本地文件添加到 i18next:

packageEnFiles.forEach(file => {
  i18n.addResourceBundle('en', file.name, file.contents);
});
因为我在 react-native 应用程序中没有在运行时可用的节点,但 babel 在编译时有。
2021-03-13 15:52:18
为什么不使用i18next-fs-backend
2021-04-12 15:52:18

我发现动态路径require()在以静态字符串开头时有效。例如require("./" + path)有效,而require(path)无效。

我以前试过这个,它在 React(使用 CRA/Gatsby/NextJS)中很有效,但在 React Native 中则不然。你真的能够在 React Native 中使用它吗?是否还有其他配置,例如jsconfig.json/tsconfig.jsonbabal.config.js
2021-04-07 15:52:18

如果需要在多个本地存储的图片之间切换,也可以这样使用:

        var titleImg;
        var textColor;
        switch (this.props.data.title) {
        case 'Футбол':
            titleImg = require('../res/soccer.png');
            textColor = '#76a963';
            break;
        case 'Баскетбол':
            titleImg = require('../res/basketball.png');
            textColor = '#d47b19';
            break;
        case 'Хоккей':
            titleImg = require('../res/hockey.png');
            textColor = '#3381d0';
            break;
        case 'Теннис':
            titleImg = require('../res/tennis.png');
            textColor = '#d6b031';
            break;
        }

在这个片段中,我改变了变量titleImgtextColorprops。我已将此代码段直接放入render()方法中。