如何为 React 元素创建唯一键? [英] How to create unique keys for React elements?

查看:39
本文介绍了如何为 React 元素创建唯一键?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个 React 应用程序,它允许您创建一个列表并保存它,但是 React 一直在警告我我的元素没有唯一的键属性(元素 List/ListForm).我应该如何为用户创建的元素创建一个唯一的键道具?下面是我的 React 代码

var TitleForm = React.createClass({句柄提交:函数(e){e.preventDefault();var listName = {'name':this.refs.listName.value};this.props.handleCreate(listName);this.refs.listName.value = "";},渲染:函数(){返回 (<div><form onSubmit={this.handleSubmit}><input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/><br/><button className="btn btn-primary" type="submit">创建</button></表单>

);}});var ListForm = React.createClass({getInitialState: 函数() {返回 {items:[{'name':'item1'}],itemCount:1};},句柄提交:函数(e){e.preventDefault();var list = {'name': this.props.name, 'data':[]};var items = this.state.items;for (var i = 1; i < items.length; i++) {list.data.push(this.refs[items[i].name]);}this.props.update(list);$('#'+this.props.name).remove();},句柄点击:函数(){this.setState({项目:this.state.items.concat({'name':'item'+this.state.itemCount+1}),itemCount: this.state.itemCount+1});},句柄删除:函数(){this.setState({itemCount: this.state.itemCount-1});},渲染:函数(){var listItems = this.state.items.map(function(item) {返回 (<div><input type="text" className="list-form" placeholder="List Item" ref={item.name}/><br/>

);});返回 (<div><form onSubmit={this.handleSubmit} className="well list-form-container">{列表项}<br/><div onClick={this.handleClick} className="btn btn-primary list-button">添加</div><div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div><button type="submit" className="btn btn-primary list-button">保存</button></表单>

)}});var List = React.createClass({getInitialState: 函数() {返回 {lists:[], savedLists: []};},句柄创建:函数(列表名称){this.setState({列表:this.state.lists.concat(listName)});},更新保存:功能(列表){this.setState({保存列表:this.state.savedLists.concat(list)});},渲染:函数(){var lst = 这个;var 列表 = this.state.lists.map(function(list) {返回(<div><div key={list.name} id={list.name}><h2 key={"header"+list.name}>{list.name}</h2><ListForm update={lst.updateSaved} name={list.name}/>

)});var savedLists = this.state.savedLists.map(function(list) {var list_data = list.data;list_data.map(函数(数据){返回 (<li>{数据}</li>)});返回(<div><h2>{list.name}</h2><ul>{list_data}

)});var save_msg;if(savedLists.length == 0){save_msg = '没有保存的列表';}别的{save_msg = '保存的列表';}返回 (<div><TitleForm handleCreate={this.handleCreate}/>{列表}<h2>{save_msg}</h2>{保存列表}

)}});ReactDOM.render(<List/>,document.getElementById('app'));

我的 HTML:

<h1>标题</h1><div id="app" class="center"></div>

解决方案

创建唯一键的方法有很多,最简单的方法是在迭代数组时使用索引.

>

示例

 var lists = this.state.lists.map(function(list, index) {返回(<div key={index}><div key={list.name} id={list.name}><h2 key={"header"+list.name}>{list.name}</h2><ListForm update={lst.updateSaved} name={list.name}/>

)});

无论你在哪里查看数据,这里this.state.lists.map,你都可以传递第二个参数function(list, index) 到回调,这将是它的 index 值,它对于数组中的所有项目都是唯一的.

然后你可以像使用它

你也可以在这里做同样的事情

 var savedLists = this.state.savedLists.map(function(list, index) {var list_data = list.data;list_data.map(函数(数据,索引){返回 (<li key={index}>{data}</li>)});返回(<div key={index}><h2>{list.name}</h2><ul>{list_data}

)});

编辑

但是,正如用户 Martin Dawson 在下面的评论中指出的那样,这并不总是理想的.

那么解决方案是什么?

很多

示例:

const generateKey = (pre) =>{return `${ pre }_${ new Date().getTime() }`;}const savedLists = this.state.savedLists.map( list => {const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );返回(<div key={ generateKey(list.name) }><h2>{ list.name }</h2><ul>{列表数据}

)});

I am making a React app that allows you to make a list and save it, but React has been giving me a warning that my elements don't have a unique key prop (elements List/ListForm). How should I create a unique key prop for user created elements? Below is my React code

var TitleForm = React.createClass({
    handleSubmit: function(e) {
        e.preventDefault();
        var listName = {'name':this.refs.listName.value};
        this.props.handleCreate(listName);
        this.refs.listName.value = "";
    },
    render: function() {
        return (
            <div>
                <form onSubmit={this.handleSubmit}>
                    <input className='form-control list-input' type='text' ref='listName' placeholder="List Name"/>
                    <br/>
                    <button className="btn btn-primary" type="submit">Create</button>
                </form>
            </div>
        );
    }
});

var ListForm = React.createClass({
    getInitialState: function() {
        return {items:[{'name':'item1'}],itemCount:1};
    },
    handleSubmit: function(e) {
        e.preventDefault();
        var list = {'name': this.props.name, 'data':[]};
        var items = this.state.items;
        for (var i = 1; i < items.length; i++) {
            list.data.push(this.refs[items[i].name]);
        }
        this.props.update(list);
        $('#'+this.props.name).remove();
    }, 
    handleClick: function() {
        this.setState({
            items: this.state.items.concat({'name':'item'+this.state.itemCount+1}),
            itemCount: this.state.itemCount+1
        });
    },
    handleDelete: function() {
        this.setState({
            itemCount: this.state.itemCount-1
        });
    },
    render: function() {
        var listItems = this.state.items.map(function(item) {
            return (
                <div>
                    <input type="text" className="list-form" placeholder="List Item" ref={item.name}/>
                    <br/>
                </div>
            );
        });
        return (
            <div>
                <form onSubmit={this.handleSubmit} className="well list-form-container">
                    {listItems}
                    <br/>
                    <div onClick={this.handleClick} className="btn btn-primary list-button">Add</div>
                    <div onClick={this.handleDelete} className="btn btn-primary list-button">Delete</div>
                    <button type="submit" className="btn btn-primary list-button">Save</button>
                </form>
            </div>
        )
    }
});


var List = React.createClass({
    getInitialState: function() {
        return {lists:[], savedLists: []};
    },
    handleCreate: function(listName) {
        this.setState({
            lists: this.state.lists.concat(listName)
        });
    },
    updateSaved: function(list) {
        this.setState({
            savedLists: this.state.savedLists.concat(list)
        });
    },
    render: function() {
        var lst = this;
        var lists = this.state.lists.map(function(list) {
            return(
                <div>
                    <div key={list.name} id={list.name}>
                        <h2 key={"header"+list.name}>{list.name}</h2>
                        <ListForm update={lst.updateSaved} name={list.name}/>
                    </div>
                </div>
            )
        });
        var savedLists = this.state.savedLists.map(function(list) {
            var list_data = list.data;
            list_data.map(function(data) {
                return (
                    <li>{data}</li>
                )
            });
            return(
                <div>
                    <h2>{list.name}</h2>
                    <ul>
                        {list_data}
                    </ul>
                </div>
            )
        });
        var save_msg;
        if(savedLists.length == 0){
            save_msg = 'No Saved Lists';
        }else{
            save_msg = 'Saved Lists';
        }
        return (
            <div>
                <TitleForm handleCreate={this.handleCreate} />
                {lists}
                <h2>{save_msg}</h2>
                {savedLists}
            </div>
        )
    }
});

ReactDOM.render(<List/>,document.getElementById('app'));

My HTML:

<div class="container">
    <h1>Title</h1>
    <div id="app" class="center"></div>
</div>

解决方案

There are many ways in which you can create unique keys, the simplest method is to use the index when iterating arrays.

Example

    var lists = this.state.lists.map(function(list, index) {
        return(
            <div key={index}>
                <div key={list.name} id={list.name}>
                    <h2 key={"header"+list.name}>{list.name}</h2>
                    <ListForm update={lst.updateSaved} name={list.name}/>
                </div>
            </div>
        )
    });

Wherever you're lopping over data, here this.state.lists.map, you can pass second parameter function(list, index) to the callback as well and that will be its index value and it will be unique for all the items in the array.

And then you can use it like

<div key={index}>

You can do the same here as well

    var savedLists = this.state.savedLists.map(function(list, index) {
        var list_data = list.data;
        list_data.map(function(data, index) {
            return (
                <li key={index}>{data}</li>
            )
        });
        return(
            <div key={index}>
                <h2>{list.name}</h2>
                <ul>
                    {list_data}
                </ul>
            </div>
        )
    });

Edit

However, As pointed by the user Martin Dawson in the comment below, This is not always ideal.

So whats the solution then?

Many

Example:

const generateKey = (pre) => {
    return `${ pre }_${ new Date().getTime() }`;
}

const savedLists = this.state.savedLists.map( list => {
    const list_data = list.data.map( data => <li key={ generateKey(data) }>{ data }</li> );
    return(
        <div key={ generateKey(list.name) }>
            <h2>{ list.name }</h2>
            <ul>
                { list_data }
            </ul>
        </div>
    )
});

这篇关于如何为 React 元素创建唯一键?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆