反应:Javascript筛选器搜索未在退格上工作

反应:Javascript筛选器搜索未在退格上工作,javascript,reactjs,filter,setstate,Javascript,Reactjs,Filter,Setstate,我正在尝试基于输入文本进行简单的筛选,但它有一个bug,当我按下“backspace”时,它应该基于原始数组而不是之前筛选的数组进行重新筛选。我知道问题是什么:每次过滤时,我都会更改原始任务。我知道我应该做一些事情,比如制作原始数组的副本,并根据副本进行过滤。但我只是不知道如何在反应中做到这一点 下面是我的代码: export class Main extends Component { constructor(pros) { super(pros) th

我正在尝试基于输入文本进行简单的筛选,但它有一个bug,当我按下“backspace”时,它应该基于原始数组而不是之前筛选的数组进行重新筛选。我知道问题是什么:每次过滤时,我都会更改原始任务。我知道我应该做一些事情,比如制作原始数组的副本,并根据副本进行过滤。但我只是不知道如何在反应中做到这一点

下面是我的代码:

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>
        )
    }
}
导出类主扩展组件{
建造师(专业人员){
超级(专业)
此.state={
任务:[
{
id:1,
内容:“莎拉的医生和疫苗”,
截止日期:2020-08-29,
已完成:false
},
{
id:2,
内容:“垃圾袋/口罩/儿童津贴”,
截止日期:2020-08-28,
已完成:false
},
{
id:3,
内容:“申请葡萄牙国籍”,
截止日期:2020-09-31,
已完成:false
},
{
id:4,
内容:“我的注册卡”,
截止日期:2020-09-28,
已完成:false
}
]
}
handleSearch=(e)=>{
让searchValue=e.target.value
console.log(searchValue)
让filteredTasks=this.state.tasks.filter(task=>{
return task.content.toLowerCase().includes(searchValue.toLowerCase())
})
this.setState(state=>({
任务:filteredTasks
}))
}
render(){
返回(
好{this.state.dayPeriod}!&hearts;{this.state.userName}
全选
身份证件
内容
{/*在*/}上创建
应得的
完整的
{this.state.tasks.reverse().map((el,i)=>(
{el.completed=!el.completed}}>
{el.id}
{el.content}
{/*{new Date().getFullYear()}-{new Date().getMonth().tolocalString('en-US',{minimumIntegerDigits:2,useGrouping:false})}-{new Date().getDate().tolocalString('en-US',{minimumIntegerDigits:2,useGrouping:false})}/}
{el.due}
{el.completed==false?'N':'Y'}
))}
{/*{this.listTasks()}*/}
)
}
}

最好将
handleSearch
功能更改为:

 handleSearch = (e) => {
       setState({searchValue: e.target.value})
    }
并处理地图中的过滤器:

this.state.tasks.reverse()
.filter(task => task.content.toLowerCase().includes(searchValue.toLowerCase()))
.map(...


最好将
handleSearch
功能更改为:

 handleSearch = (e) => {
       setState({searchValue: e.target.value})
    }
并处理地图中的过滤器:

this.state.tasks.reverse()
.filter(task => task.content.toLowerCase().includes(searchValue.toLowerCase()))
.map(...


您正在覆盖源数据。您应该保留一个存储源数据的变量

const TASK = [
  {
    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
  }
];

// ...

  constructor(pros) {
    super(pros);
    this.state = {
      tasks: [...TASK]
    };
  }

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

// ...
代码沙盒演示


您正在覆盖源数据。您应该保留一个存储源数据的变量

const TASK = [
  {
    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
  }
];

// ...

  constructor(pros) {
    super(pros);
    this.state = {
      tasks: [...TASK]
    };
  }

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

// ...
代码沙盒演示


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

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>
        )
    }
}
导出类主扩展组件{
建造师(专业人员){
超级(专业)
此.state={
任务:[
{
id:1,
内容:“莎拉的医生和疫苗”,
截止日期:2020-08-29,
已完成:false
},
{
id:2,
内容:“垃圾袋/口罩/儿童津贴”,
截止日期:2020-08-28,
已完成:false
},
{
id:3,
内容:“申请葡萄牙国籍”,
截止日期:2020-09-31,
已完成:false
},
{
id:4,
内容:“我的注册卡”,
截止日期:2020-09-28,
已完成:false
}
],
搜索值:“
}
handleSearch=(e)=>{
this.setState({searchValue:e.target.value})
}
filterResults=()=>{
如果(!this.state.searchValue)返回this.state.tasks
返回此.state.tasks.filter(任务=>{
return task.content.toLowerCase().includes(this.state.searchValue.toLowerCase())
})
}
render(){
返回(
好{this.state.dayPeriod}!&hearts;{this.state.userName}
全选
身份证件
内容
{/*在*/}上创建
应得的
完整的
{filterResults().reverse().map((el,i)=>(