首页 > 解决方案 > React 使用 map 迭代嵌套数组/对象。渲染每个地图功能是否必须返回?

问题描述

我是反应新手。我正在构建一个小功能组件来呈现口袋妖怪的弱点。

它将存储在状态(pokemonState.types)中的口袋妖怪类型作为每种类型的对象数组,将类型与包含所有类型有效性的 JSON 文件进行比较(见下文)。

types_data.json

  "electric": {
"attack": {
  "double": ["flying", "water"],
  "half": ["dragon", "electric", "grass"],
  "zero": ["ground"]
},
"defense": {
  "half": ["electric", "flying", "steel"],
  "double": ["ground"],
  "zero": []
}

为了获得我想要的数据,我需要进行多次迭代,并且我注意到我的组件仅在我指定 return 关键字并将我的元素包装在 HTML 标记中时才会呈现。

不呈现任何内容的函数(但 console.log 不返回未定义)

  const pokemonTypeChart = () => {
if (!_.isEmpty(pokemonState)) {
  const allTypes = Object.entries(types_data);
  const typeEffectiveness = allTypes.map(([key, value]) => {
    pokemonState.types.map((el) => {
      if (el.type.name === key) {
        console.log(key, value);
        return <p>{el}</p>;
      }
    });
  });
  return (
    <div>
      <h1>Test</h1>
      <p>{typeEffectiveness}</p>
    </div>
  );
}};

运行良好的功能:

const pokemonTypeChart = () => {
if (!_.isEmpty(pokemonState)) {
  const allTypes = Object.entries(types_data);
  return (
    <div>
      <h1>Type Effectiveness</h1>
      {allTypes.map(([key, value]) => {
        return (
          <>
            {pokemonState.types.map((el, i) => {
              if (el.type.name === key)
                return <h3 key={i}>{value.defense.double}</h3>;
            })}
          </>
        );
      })}
    </div>
  );
}};

我的问题是:

谢谢你的帮助。

标签: javascriptarraysreactjsjsonobject

解决方案


您的第一个功能不起作用的原因是您正在返回<p>{el}</p>.

el等于一个对象&你期待一个字符串。

具体来说,在这种情况下,它类似于{type:{name: "electric"}

如果您将那条线从 更改return <p>{el}</p>;return <p>{el.type.name}</p>;,那么这会修复我们的内部.map,因此您越来越接近。

但是,您还有第二个问题......外部.map函数没有返回任何内容。您的typeEffectiveness变量是我们最终要渲染的,并且该变量等于调用的结果allTypes.map。当您的嵌套pokemonState.types.map函数返回到父.map函数时,您的父.map函数没有返回语句。

最终,您正在渲染{typeEffectiveness},所以我们必须确保该变量是一个将渲染到 DOM 的反应元素数组。

还有其他几个小问题。也就是说,我们必须在 <p>{typeEffectiveness}</p>此处删除段落标签,否则我们将得到嵌套p标签,因为typeEffectiveness列表中的每个项目都已包含在<p></p>.

最后,您还应该将关键标签添加到列表项中。 <p key="{el.type.name}">{el.type.name}</p>

在此处深入了解有关列表和键的文档: https ://reactjs.org/docs/lists-and-keys.html

以下代码是您的第一个函数的调试版本。

我还在下面包含了您的部分功能的重构版本。types_data当我们真的只关心我们的pokemonState.

const e = React.createElement;

const pokemonState ={types: [{type:{name: "electric"}}]};
let types_data = {
    "electric": {
        "attack": {
            "double": ["flying", "water"],
            "half": ["dragon", "electric", "grass"],
            "zero": ["ground"]
        },
        "defense": {
            "half": ["electric", "flying", "steel"],
            "double": ["ground"],
            "zero": []
        }
    }
};


const PokemonTypeChart = () => {
    if (!_.isEmpty(pokemonState)) {
        const allTypes = Object.entries(types_data);
        const typeEffectiveness = allTypes.map(([key, value]) => {
            return (pokemonState.types.map((el) => {
                if (el.type.name === key) {
                    return (
                    <p key="{el.type.name}">{el.type.name}</p>
                    );
                    
                }
            }));
        });
        return (
            <div>
                <h1>Test</h1>
                {typeEffectiveness}
            </div>
        );
    }};




const domContainer = document.querySelector('#pokemon');
ReactDOM.render(e(PokemonTypeChart), domContainer);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script>
    
    <div id="pokemon"></div>

const e = React.createElement;

const pokemonState ={types: [{type:{name: "electric"}}]};
let types_data = {
    "electric": {
        "attack": {
            "double": ["flying", "water"],
            "half": ["dragon", "electric", "grass"],
            "zero": ["ground"]
        },
        "defense": {
            "half": ["electric", "flying", "steel"],
            "double": ["ground"],
            "zero": []
        }
    }
};


const PokemonChart = () => {
    if (!_.isEmpty(pokemonState)) {
        const plistItems = pokemonState.types.map((item) => 
            types_data[item.type.name].defense.double.map((i) => 
                <p key={i}>{i}</p>
            ));
        return (
            <div>
                <h1>Type Effectiveness</h1>
                {plistItems}
            </div>
        );
    }};
const domContainer = document.querySelector('#pokemon');
ReactDOM.render(e(PokemonChart), domContainer);
<script src="https://unpkg.com/react@16/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js" crossorigin></script>
    <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.1/underscore-umd-min.js"></script>
    
    <div id="pokemon"></div>


推荐阅读