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

IT技术 javascript reactjs
2021-03-27 04:18:08

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

我越来越

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

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

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;

我的登录组件如下:

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;

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

更新

登录表单组件:

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;

路线文件:

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;

主页组件

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>
);
2个回答

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

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

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

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

App 组件是从路由文件中调用的,来自 React Router。我用那个文件更新了我的问题。
2021-05-23 04:18:08
我更新了我的问题。但是我没有在任何地方迭代数组,我在任何地方都没有地图。
2021-05-28 04:18:08
嗯。this.props.children您的App组件中到底传递了什么也许这是一个数组?其他一切对我来说都很好。
2021-06-02 04:18:08
不,我的意思是传递给您的App组件的孩子>> <App>{//the children you are passing here}</App>. 这是可以传递数组的地方。请参阅facebook.github.io/react/tips/children-props-type.html顶部的说明
2021-06-04 04:18:08
我更新了 App 组件的代码。状态通过;那只是一个数字。
2021-06-05 04:18:08

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

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

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

关键的重要性在这里得到了很好的解释

我当然感谢您更新您的答案,但请实际您的答案中发布代码:链接可以而且确实会失效。如果代码示例是您从其他地方获得的,而不是您自己创建的,请务必添加归属链接,但仍将代码发布在您的实际答案中。
2021-05-26 04:18:08
谢谢,@JaredSmith!编辑了我的答案。
2021-06-04 04:18:08
虽然肯定是正确的,但通过添加代码示例可以改进此答案。
2021-06-10 04:18:08
谢谢@JaredSmith 的反馈。如果您认为我仍然缺少任何内容,请纠正我。
2021-06-18 04:18:08