【问题标题】:Keys should be unique so that components maintain their identity across updates密钥应该是唯一的,以便组件在更新时保持其身份
【发布时间】:2018-09-24 14:27:01
【问题描述】:

我有一个反应组件,它呈现已从 API 调用并设置为 setOfAllBooks 状态的项目列表。每当我搜索该项目时,setOfAllBooks 状态都会被搜索项过滤掉,并且结果会保存在 searchedBooks 状态中。然后将 searchedBooks 的结果传递给 Table 组件并呈现在列表中。此时它可以正常工作,但是当我搜索另一个项目时,它会聚集在表中。我想要做的是,每当我在搜索了 previos 术语之后搜索新项目时,我希望清除表格组件中的列表项目,以便为已搜索的新项目让路。

import React, { Component } from 'react';
import './Home.css'
import axios from 'axios';
import Autosuggest from 'react-autosuggest';

var books = []

const getSuggestions = value => {
    const inputValue = value.trim().toLowerCase();
    const inputLength = inputValue.length;

    return inputLength === 0 ? [] : books.filter(book =>
        book.title.toLowerCase().slice(0, inputLength) === inputValue);
};

const getSuggestionValue = suggestion => suggestion.title;

const renderSuggestion = suggestion => (
    <div>
        {suggestion.title}
    </div>
);

const Table = ({ data }) => (
    <table class="table table-hover">
        <thead>
            <tr class="table-primary">
                <th scope="col">Title</th>
                <th scope="col">Author</th>
                <th scope="col">ISBN</th>
                <th scope="col">No. Of Copies</th>
            </tr>
        </thead>
        <tbody>
            {data.map(row => 
                <TableRow row={row} />
            )}

        </tbody>
    </table>
)

const TableRow = ({ row }) => (
    <tr class="table-light">
        <th scope="row" key={row.title}>{row.title}</th>
        <td key={row.author}>{row.author}</td>
        <td key={row.isbn}>{row.isbn}</td>
        <td key={row.isbn}>24</td>
    </tr>
)


class Home extends Component {
    constructor(props) {
        super(props);

        this.state = {
            value: '',
            suggestions: [],
            setOfAllBooks: [],
            searchedBooks: []
        };

        this.searchBook = this.searchBook.bind(this);
    }

    componentDidMount(){
        axios.get('/api/book/viewAll')
            .then(res => {
                this.setState({ setOfAllBooks: res.data });
                books = this.state.setOfAllBooks;
                console.log(this.state.setOfAllBooks)
            })
    }


    onChange = (event, { newValue }) => {
        this.setState({
            value: newValue
        });
    };

    onSuggestionsFetchRequested = ({ value }) => {
        this.setState({
          suggestions: getSuggestions(value)
        });
      };

    onSuggestionsClearRequested = () => {
        this.setState({
            suggestions: []
        });
    }

    searchBook(event){
        event.preventDefault();

        this.setState({value: this.state.value});

        this.state.searchedBooks = this.state.setOfAllBooks.filter(book => book.title == this.state.value);
        this.setState({searchedBook: []})

        console.log(this.state.searchedBook);
    }

    render() {
        const { value, suggestions } = this.state;

        const inputProps = {
            placeholder: 'Enter the name of the book',
            value,
            onChange: this.onChange
        }
        return (
            <div class="form-group col-lg-4">
                <label for="exampleInputEmail1">Email address</label>
                    <Autosuggest
                        suggestions={suggestions}
                        onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
                        onSuggestionsClearRequested={this.onSuggestionsClearRequested}
                        getSuggestionValue={getSuggestionValue}
                        renderSuggestion={renderSuggestion}
                        inputProps={inputProps}
                        id="searchFor"
                    />
                    <div className=" form-group">
                        <label htmlFor="searchFor">&nbsp;</label>
                        <button class="form-control btn btn-success" type="submit" onClick={this.searchBook}>Search</button>
                    </div>
                    <Table data={this.state.searchedBooks} />
            </div>
        )
    }
}

export default Home;

结果

错误

【问题讨论】:

  • &lt;TableRow row={row} /&gt; -- 它需要一个 key 属性。

标签: reactjs


【解决方案1】:

您需要将key 属性添加到TableRow 组件中作为&lt;TableRow key={row.title} row={row} /&gt;。删除您现在拥有的key

....A good rule of thumbmap() 调用中的元素需要keys

... 数组中使用的键在它们的兄弟中应该是唯一的。 . Doc.

因此,您用于keytitle 似乎仍会引发警告,因为它们不是uniqe。如果您在 row 对象中有 ID 属性,请使用该属性。将key 添加到TableRow 将删除第一个警告,但其他警告仍然存在,直到title 在所有数据中都没有uniq 值。

【讨论】:

  • 谢谢。完美运行。
猜你喜欢
  • 2019-06-12
  • 1970-01-01
  • 2020-05-15
  • 1970-01-01
  • 1970-01-01
  • 2019-03-29
  • 1970-01-01
  • 2016-11-30
  • 1970-01-01
相关资源
最近更新 更多