0

我有这段代码来制作要在屏幕上显示的图像数组。但是,我不知道 images 数组中的 key 属性是什么意思。理想情况下,只要单击其中一张图像,我就想更改图像的 src。如果我在图像中添加idorclassName属性,并使用它进行查找,document.getElementById我会收到以下警告:Warning: Prop `%s` did not match. Server: %s Client: %s%s当我呈现页面时。我正在为这个项目使用 react 和 razzle。有人能告诉我如何做到这一点吗?

var shuffle = require("shuffle-array"),
    animals = [
      "frog0",
      "frog1",
      // ...
      "seal1",
      "armadillo0",
      "armadillo1"
    ];

function whatami(img) {
  alert(img);
}
var images = shuffle(animals).map(image => {
  return (
    <img
      onClick={() => {
        whatami(image);
      }}
      key={image}
      src={"/animalgameback.jpg"}
    />
  );
});
const App = () => (
  <div>
    <h3>My razzle app</h3>
    <div>{images}</div>
  </div>
);

export default App;
4

2 回答 2

2

您的方法在这里有很多问题。我强烈建议阅读有关如何在 ReactJS 中编写 Javascript 的官方 React 文档。

让我们介绍一些基础知识。首先,你真的不应该document.getElementById在 React 中使用(除非情况很糟糕并且你试图破解第三方库)。大多数情况下,您使用 propref来引用挂载在 DOM 中的 React 节点。但是,只是对那些学习的人的一些建议,使用参考文献让你有乐趣,这样你就知道如何使用它们以及它们做了​​什么。但。我建议,如果您“需要”引用或“需要”在运行时直接与 React 组件对话,那么您可能做错了什么。

现在,由于您正在尝试根据用户事件或交互来“更改”某些内容,因此这是状态管理的完美用例。由于此更新或更改,React 具有让每个组件自封装有状态对象并使用这些状态“触发”或重新渲染组件中的事物的能力。

什么是钥匙?它是一个唯一标识符,您可以在每个呈现的 JSX 组件上使用它来显示虚拟 DOM 和真实 DOM,该组件旨在按原样重新呈现,而不是卸载、更改和重新安装。一个键允许 React 跟踪哪些组件是预期的,而不是刚刚重生或安装的。你总是写一个 JSX 元素的键作为唯一的 id。如果您使 2 个 id 相同(试一试并查看 :))您会注意到它们在屏幕上呈现为 1 并且一个替换另一个。

以下是我的写法:我制作了一个图像作为“查看器”来显示单击了哪个图像,以及附加到图像以更改状态的单击事件处理程序。渲染函数检测图像源更改并重新渲染组件。因此,新的源被接收、使用和渲染。

编码

import React, { Component } from 'react';

const ANIMAL_DATA = [
    'frog0','frog1','sheep0','sheep1','snail0','snail1','mouse0','mouse1','bat0','bat1','walrus0',
    'walrus1','giraffe0','giraffe1','zebra0','zebra1','dog0','dog1','octopus0','octopus1','hippo0',
    'hippo1','camel0','camel1','pig0','pig1','rhino0','rhino1','rooster0','rooster1','panda0','panda1',
    'turtle0','turtle1','raccoon0','raccoon1','polarbear0','polarbear1','lion0','lion1','bison0',
    'bison1','orca0','orca1','snake0','snake1','shark0','shark1','toucan0','toucan1','butterfly0',
    'butterfly1','anteater0','anteater1','seal0','seal1','armadillo0','armadillo1'
]

class App extends Component {

    constructor(props) {
        super(props);

        this.state = {
            imageSource: 'animalgameback',
        };
    }
    
    render() {
        const { imageSource } = this.state;

        return (
            <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center' }}>
                <img style={{ width: 143, height: 'auto' }} source={require(`/${imageSource}.jpg`)} />

                { this.renderAnimalImages() }
            </div>
        );
    }

    renderAnimalImages() {
        let images = [];

        ANIMAL_DATA.forEach((animal, animalIndex) => {
            // Be careful when assigning "onclick" methods to images,
            // you are better off sticking with W3C rules on this. Use elements
            // meant for "clicking" or "being clicked", i.e. <a>, <button>, etc
            images.push(
                <img
                    src={`/${animal}.jpg`}
                    key={`anima_image_${animalIndex}`}
                    onClick={this.__handleImageClick(animal)} />
            );
        });

        return images;
    }


    __handleImageClick = animal => event => {
        this.setState({ imageSource: animal });
    };
}


export default App;

于 2020-04-02T17:50:33.613 回答
-1

key属性用作身份声明。它帮助渲染引擎决定应该重新渲染哪些元素。

文档中对此进行了很好的解释。

于 2020-04-02T17:23:26.543 回答