javascript - react : Javascript filter search not working on backspace

标签 javascript reactjs filter setstate

我正在尝试根据输入文本做一个简单的过滤器,但它有一个错误,当我按下“退格键”时,它应该根据原始数组而不是之前过滤的数组重新过滤。我知道问题出在哪里:每次过滤时我都更改了原始任务。而且我知道我应该做一些事情,比如制作原始数组的副本并根据副本进行过滤。但我只是不知道如何在 react 中实现这一目标。

下面是我的代码:

export class Main extends Component {
    constructor(pros) {
        super(pros)
        this.state = {
            tasks: [
                {
                    id: 1,
                    content: "Sara's doctor and vaccine",
                    due: '2020-08-29',
                    completed: false
                },
                {
                    id: 2,
                    content: "Trash bags / facial masks / child allowance",
                    due: '2020-08-28',
                    completed: false
                },
                {
                    id: 3,
                    content: "Apply for Portugal nationality",
                    due: '2020-09-31',
                    completed: false
                },
                {
                    id: 4,
                    content: "My registration card",
                    due: '2020-09-28',
                    completed: false
                }
            ]
        }


    handleSearch = (e) => {
        let searchValue = e.target.value
        console.log(searchValue)
        let filteredTasks = this.state.tasks.filter(task => {
            return task.content.toLowerCase().includes(searchValue.toLowerCase())
        })
        this.setState(state => ({
            tasks: filteredTasks
        }))
    }


    render() {
        return (
            <div>
                <div style={{ textAlign: 'right' }}><input type='search' onKeyUp={this.handleSearch} id='search' name='search' placeholder='Search Tasks' autoComplete='on' style={{ width: '60%', margin: '15px 15px 45px auto' }} /></div>

                <table>
                    <caption>Good {this.state.dayPeriod}! &hearts; {this.state.userName}</caption>
                    <thead>
                        <tr>
                            <th>
                                <button type='button' onClick={this.handleSelect}>Select All</button>
                            </th>
                            <th>ID</th>
                            <th>Content</th>
                            {/* <th>Created On</th> */}
                            <th>Due</th>
                            <th>Completed</th>
                        </tr>
                    </thead>
                    <tbody>
                        {this.state.tasks.reverse().map((el, i) => (
                            <tr key={i} className='row' style={{ textDecoration: el.completed ? this.state.textDecoration : 'none', color: el.completed ? this.state.color : '#000000' }}>
                                <td>
                                    <input type='checkbox' checked={el.completed} onChange={() => { el.completed = !el.completed }}></input>
                                </td>
                                <td className='taskID' style={{ verticalAlign: 'text-top' }}>{el.id}</td>
                                <td className='taskContent'>{el.content}</td>
                                {/* <td style={{whiteSpace: 'nowrap'}}>{new Date().getFullYear()}-{new Date().getMonth().toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}-{new Date().getDate().toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}</td> */}
                                <td style={{ whiteSpace: 'nowrap' }}>{el.due}</td>
                                <td>{el.completed === false ? 'N' : 'Y'}</td>
                            </tr>
                        ))}

                        {/* {this.listTasks()} */}
                    </tbody>
                </table>
            </div>
        )
    }
}

最佳答案

有很多方法可以实现您的要求,但最简单的方法是不更改状态,只更改应呈现的内容。 在您的代码之上,我添加了过滤器,因此状态保持不变,但只有过滤器适用于结果:

export class Main extends Component {
    constructor(pros) {
        super(pros)
        this.state = {
            tasks: [
                {
                    id: 1,
                    content: "Sara's doctor and vaccine",
                    due: '2020-08-29',
                    completed: false
                },
                {
                    id: 2,
                    content: "Trash bags / facial masks / child allowance",
                    due: '2020-08-28',
                    completed: false
                },
                {
                    id: 3,
                    content: "Apply for Portugal nationality",
                    due: '2020-09-31',
                    completed: false
                },
                {
                    id: 4,
                    content: "My registration card",
                    due: '2020-09-28',
                    completed: false
                }
            ],
            searchValue: ""
        }


    handleSearch = (e) => {
        this.setState({ searchValue: e.target.value })
    }

    filterResults = () => {
        if(!this.state.searchValue) return this.state.tasks
        return this.state.tasks.filter(task => {
            return task.content.toLowerCase().includes(this.state.searchValue.toLowerCase())
        })
    }


    render() {
        return (
            <div>
                <div style={{ textAlign: 'right' }}><input type='search' onKeyUp={this.handleSearch} id='search' name='search' placeholder='Search Tasks' autoComplete='on' style={{ width: '60%', margin: '15px 15px 45px auto' }} /></div>

                <table>
                    <caption>Good {this.state.dayPeriod}! &hearts; {this.state.userName}</caption>
                    <thead>
                        <tr>
                            <th>
                                <button type='button' onClick={this.handleSelect}>Select All</button>
                            </th>
                            <th>ID</th>
                            <th>Content</th>
                            {/* <th>Created On</th> */}
                            <th>Due</th>
                            <th>Completed</th>
                        </tr>
                    </thead>
                    <tbody>
                        {filterResults().reverse().map((el, i) => (
                            <tr key={i} className='row' style={{ textDecoration: el.completed ? this.state.textDecoration : 'none', color: el.completed ? this.state.color : '#000000' }}>
                                <td>
                                    <input type='checkbox' checked={el.completed} onChange={() => { el.completed = !el.completed }}></input>
                                </td>
                                <td className='taskID' style={{ verticalAlign: 'text-top' }}>{el.id}</td>
                                <td className='taskContent'>{el.content}</td>
                                {/* <td style={{whiteSpace: 'nowrap'}}>{new Date().getFullYear()}-{new Date().getMonth().toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}-{new Date().getDate().toLocaleString('en-US', {minimumIntegerDigits: 2, useGrouping:false})}</td> */}
                                <td style={{ whiteSpace: 'nowrap' }}>{el.due}</td>
                                <td>{el.completed === false ? 'N' : 'Y'}</td>
                            </tr>
                        ))}

                        {/* {this.listTasks()} */}
                    </tbody>
                </table>
            </div>
        )
    }
}

关于javascript - react : Javascript filter search not working on backspace,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63794671/

相关文章:

javascript - 从未被称为 Sinon Spy

javascript - 在 HIghCharts.js 中查找绘图线的 Y 轴值

javascript - 如何隐藏底部的CSS

javascript - Xeditable 不工作 AngularJS

javascript - 渲染没有返回任何内容,但我不知道为什么

python - Pandas:使用 groupby 计算添加标志

javascript - Jquery 文件上传插件无法在 Internet Explorer 11 中拖放文件

javascript - 在 React.js 中使用 Dropzone 时如何将图像上传到 Firebase 存储并获取图像的下载 URL

javascript - 日期范围过滤器不起作用

r - 根据子组 R 过滤数据