Javascript React - 数组或迭代器中的每个孩子都应该有一个唯一的“键”道具

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37651660/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 20:34:20  来源:igfitidea点击:

React - Each child in an array or iterator should have a unique "key" prop

javascriptreactjs

提问by Boky

I have a problem with the key props in a React JS component.

我在 React JS 组件中的关键道具有问题。

I'm getting

我越来越

Warning: Each child in an array or iterator should have a unique "key" prop. Check the render method of Login. It was passed a child from App.

警告:数组或迭代器中的每个子元素都应该有一个唯一的“key”属性。检查登录的渲染方法。它是从 App 传过来的一个孩子。

warning in console log. App component is as follows :

控制台日志中的警告。应用组件如下:

import React from 'react';
import Header from '../common/header';
import HeaderCompact from '../common/headerCompact';
import Footer from '../common/footer';


class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      lang: 1
    };
  }

  changeLang(name, event) {
    event.preventDefault();
    switch (name) {
      case "fra" :
        this.setState({lang: 2});
        break;
      case "ger" :
        this.setState({lang: 3});
        break;
      case "ned" :
        this.setState({lang: 4});
        break;
      default:
        this.setState({lang: 1});
    }
  }


  render() {
    let currentRoute = this.props.location.pathname.slice(1);
    let header = currentRoute === "" ? <Header onClick={this.changeLang} lang={this.state.lang}/> :
      <HeaderCompact currentRoute={currentRoute} onClick={this.changeLang} lang={this.state.lang}/>;
    return (
      <div>
        {header}
        {React.cloneElement(this.props.children, {lang: this.state.lang})}
        <Footer lang={this.state.lang}/>
      </div>

    );
  }
}

export default App;

And my login component is as follows :

我的登录组件如下:

import React from 'react';
import LoginForm from './loginForm';

const Login = ({currentLanguage}) => {

    const language = currentLanguage;

    return (
        <div className="container">
            <div className="row">
                <p className="col-lg-4 col-xs-12 col-md-4 loginTitle noPadding">{language.loginTitle}</p>
                <div className="col-lg-8 col-xs-12 col-md-8 loginForm noPadding">
                    <LoginForm currentLanguage={language}/>
                </div>
            </div>
        </div>
    );
};

export default Login;

I'm still new in React and I'm not sure what should I pass like a key and where?

我还是 React 的新手,我不确定我应该像钥匙一样传递什么以及在哪里传递?

UPDATE

更新

LoginForm component :

登录表单组件:

import React from 'react';
import {Link} from 'react-router';

import TextInput from '../../common/formElements/textInput';
import LoginButton from '../../common/formElements/button';

class LoginForm extends React.Component {

    constructor(props, context) {
        super(props, context);

        this.state = {
            loginData: {
                username: '',
                password: ''
            },
            errors: {}
        };

        this.buttonClickHandle = this.buttonClickHandle.bind(this);
        this.loginHandle = this.loginHandle.bind(this);
    }

    loginHandle(event) {
        let field = event.target.name;
        let value = event.target.value;
        this.state.loginData[field] = value;
        return this.setState({loginData: this.state.loginData});
    }

    buttonClickHandle(event) {
        event.preventDefault();
        alert("It's clicked/n");
    }

    render() {
        const language = this.props.currentLanguage;

        return (
            <div className="contact_form">
                <form role="form" action="" method="post" id="contact_form">
                    <div className="col-lg-4 col-md-4 col-sm-4 col-xs-12 smScrPdLeft" style={{marginTop: 5}}>
                        <TextInput
                            type="text"
                            name="username"
                            label=""
                            placeholder={language.loginUsername}
                            className="templateInput loginUsername col-lg-12 col-md-12 col-sm-12 col-xs-12"
                            id="name"
                            sizeClass=""
                            onChange={this.loginHandle}
                            value={this.state.username}
                            errors={this.state.errors.username}
                        />
                    </div>
                    <div className="col-lg-4 col-md-4 col-sm-4 col-xs-12 smPadding" style={{marginTop: 5}}>
                        <TextInput
                            type="password"
                            name="password"
                            label=""
                            placeholder={language.loginPassword}
                            className="templateInput loginPassword col-lg-12 col-md-12 col-sm-12 col-xs-12"
                            id="password"
                            sizeClass=""
                            onChange={this.loginHandle}
                            value={this.state.password}
                            errors={this.state.errors.password}
                        />
                        <Link to="/" className="forgotPassLabel">{language.forgotPassword}</Link>
                    </div>
                    <div className="col-lg-4 col-md-4 col-sm-4 col-xs-12 btnLogin noPadding smScrPdRight" style={{marginTop: 4}}>
                        <LoginButton onClick={() => this.buttonClickHandle(event)} name="registration" value={language.loginBtnText} className="rightFloat" icon="user"/>
                    </div>
                </form>
            </div>
        );
    }
}

export default LoginForm;

Routes file :

路线文件:

import React from 'react';
import { IndexRoute, Route } from 'react-router';

import App from './components/App';
import HomePage from './components/HomePage';

const routes = (
    <Route path="/" component={App}>
        <IndexRoute component={HomePage}/>
    </Route>
);

export default routes;

HomePage Component

主页组件

return (
    <div>
        <div className="sidebar-menu-container" id="sidebar-menu-container">

            <div className="sidebar-menu-push">

                <div className="sidebar-menu-overlay"></div>

                <div className="sidebar-menu-inner">

                    <section className="marginOnXs" style={{width: '100%', padding: 0}}>
                        <div className="container">
                            <div className="row hideOnXS">
                                <MainSlider />
                            </div>
                        </div>

                    </section>

                    <div id="cta-1" className="onlyOnDesktop">
                        <Login currentLanguage={languageHome}/>
                    </div>

                    <section className="why-us" style={{paddingTop: 0}}>
                        <Info currentLanguage={languageHome}/>
                    </section>
                    <div className="clearfix"></div>

                    <section className="featured-listing">
                        <CarsList allCars={carsList()} currentLanguage={languageHome}/>
                    </section>

                    <section className="contactSection">
                        <ContactForm currentLanguage={languageHome}/>
                    </section>
                </div>
            </div>
        </div>
    </div>
);

回答by Richard Rutsche

I don't know how your LoginFormcomponent looks like.

我不知道你的LoginForm组件是什么样子的。

But each time you iterate over an array you have to set the keyprop to each of the resulting DOMelement as Reactneeds it to optimize the re-rendering. For example:

但是每次迭代数组时,您都必须根据需要将key道具设置为每个结果DOM元素,React以优化重新渲染。例如:

<div className="container">
        {myarray.map((element, index) => {
            return <div key={'mykey' + index}>{element}</div>;
        })}
</div>

Reactfor example will detect duplicates and only renders the first nodewith this key.

React例如将检测重复项并仅node使用 this呈现第一个key

回答by Abhishek Maheshwari

The reason behind this warning is that you have not passed 'key' property. React uses this property for optimizing the rendering process as in when something changes in React, a re-render will occur only for what all has changed.

此警告背后的原因是您尚未传递 'key' 属性。React 使用此属性来优化渲染过程,因为当 React 中的某些内容发生变化时,只会对所有已更改的内容进行重新渲染。

If our children are dynamic and in case they get shuffled with random functions or new components are introduced in the beginning of an array, the re-render is likely to get messed up. So, assigning this 'key' property helps us make sure that the state and identity of our components is maintained through multiple renders. Please find below a sample code snippet demonstrating how to pass a key.

如果我们的孩子是动态的,并且万一他们被随机函数打乱或在数组的开头引入了新组件,重新渲染可能会变得一团糟。因此,分配这个“key”属性有助于我们确保通过多次渲染维护组件的状态和身份。请在下面找到演示如何传递密钥的示例代码片段。

<MyComponent key={{item.key}}/>

The importance of key is beautifully explained here.

这里很好地解释了 key 的重要性。