密钥应该是唯一的,以便组件在更新中保持其身份

时间:2018-09-24 14:27:01

标签: reactjs

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

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;

结果 enter image description here

错误 enter image description here

1 个答案:

答案 0 :(得分:3)

您需要将key属性添加为TableRow<TableRow key={row.title} row={row} />组件中。删除您目前所在的key

  

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

     

...数组中使用的键在同级之间应该唯一。 。 Doc

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