如何卸载组件?

How do I unload components?

我有一个项目组件,我正在根据项目列表进行复制。 呈现页面并显示所有项目组件后,我想启用搜索功能。

当我执行搜索并过滤项目列表时,搜索后旧结果显示在新结果附近!

如何让它只显示搜索结果?

更新代码(工作):

class ProjectsList extends Component {

state = {
    projectsDetails: [......],
    filterKey: null
}

componentWillMount() {
    //service.getProjectDetails();
}

handleSearchChange(e) {
    this.setState({ filterKey: e.target.value });
}

render() {
    const { filterKey, projectsDetails } = this.state;

    const filteredProjects = filterKey
        ? projectsDetails.filter(item =>
            item.Name.toLowerCase().includes(filterKey.toLowerCase()) && item.FabricationConfigs !== null
        )
        : projectsDetails.filter(item =>
            item.FabricationConfigs !== null
        );

    return (
        <table width="100%">
            <tbody>
            <tr>
                <td>

                    <div className="Toolbar2">
                        <table width="100%">
                            <tbody>
                            <tr>
                                <td>
                                    <h1>Projects</h1>
                                </td>
                                <td  width="20%" align="right">
                                    <Search labelText="" id="search-1" onChange={ this.handleSearchChange.bind(this) }/>
                                </td>
                            </tr>
                            </tbody>
                        </table>
                        <hr></hr>
                    </div>
                    <div className="inline">
                        {filteredProjects.map(item =>
                            <Project
                            key={item.Name}
                            name={item.Name}
                            description={item.Description}
                            configurations={item.FabricationConfigs}/>)}
                    </div>

                </td>
            </tr>
            </tbody>
        </table>
    );
}

}

假设您正在渲染一个列表:

state = {
  list: [{code: 'a'},{code: 'b'},{code: 'c'}],
};

//some render function
<div>{this.state.list.map(item => <Item item={item} />}</div>

为了不卸载其中 ,您必须 un-render 它们。

所以你可以通过索引删除一个(例如)。您可以使用您的函数进行过滤。

removeByIndex(idx) {
  this.setState({
    list: this.state.list.filter((item, index) => index !== idx),
  });
}

因此具有上述索引的 Item 组件将被 un-rendered 并因此被卸载。

这里有几个问题。 1. 你正在用这一行改变状态:

this.state.filteredProjects = this.state.filteredProjects.filter

和这一行:

projectsComponents.push

在使用 react 时根本不推荐这样做,我相信这就是为什么您需要像 this.forceUpdate().

这样的方法的原因
  1. 您实际上并没有在渲染方法中渲染任何更新。请记住,render 中的任何内容都会在每次更新状态或新道具时 运行。因此您可以使用存储在 state 中的过滤值,获取您的列表,并根据该值存储它的过滤版本。 然后只需使用 .map.
  2. 渲染过滤后的列表

这是一个简单的 运行ning 示例:

class App extends React.Component {
  state = {
    list: [{ name: "John" }, { name: "Jane" }, { name: "Mike" }],
    filterKey: null
  };

  onFilterChange = ({ target }) => {
    this.setState({ filterKey: target.value });
  };

  render() {
    const { filterKey, list } = this.state;
    const filteredList = filterKey
      ? list.filter(item =>
          item.name.toLowerCase().includes(filterKey.toLowerCase())
        )
      : list;
    return (
      <div>
        <input
          value={filterKey}
          onChange={this.onFilterChange}
          placeholder="filter..."
        />
        <hr />
        {filteredList.map(item => (
          <div>{item.name}</div>
        ))}
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="root"/>