代码之家  ›  专栏  ›  技术社区  ›  michasaucer

使用输入响应即时搜索

  •  2
  • michasaucer  · 技术社区  · 7 年前

    我正在做我的第一个反应项目。我是JS、HTML、CSS甚至Web应用程序编程的新手。

    我想做的是一个搜索输入标签。现在看起来像这样:

    enter image description here

    如您所见,我有一些对象列表和文本输入。

    我有两个部件,我的 ProjectList.js 具有 Search.js 组件…

    class ProjectsList extends Component {
      render() {
        return (
          <div>
            <Search projects={this.props.projects} />
            <ListGroup>
              {this.props.projects.map(project => {
                return <Project project={project} key={project.id} />;
              })}
            </ListGroup>
          </div>
        );
      }
    }
    
    export default ProjectsList;
    

    …和 项目列表 显示器 Project.js :

    看起来怎么样 搜索引擎 (其未结束组件)

    class Search extends Component {
      state = {
        query: ""
      };
    
      handleInputChange = () => {
        this.setState({
          query: this.search.value
        });
      };
    
      render() {
        return (
          <form>
            <input
              ref={input => (this.search = input)}
              onChange={this.handleInputChange}
            />
            <p />
           </form>
        );
      }
    }
    
    export default Search;
    

    我的 project 有 name 财产。你能告诉我怎么编代码吗 搜索引擎 组件弹出,更改显示 projects 基于文本标签中的输入动态?例如, return Project 仅当输入的文本匹配时(我想在开始键入时动态搜索它 m …它显示开始于的所有项目 米 等)。

    如何正确地进行搜索输入?如何使其成为通用的,例如在另一个对象列表中搜索?如何从搜索返回到父组件?

    现在,在react dev工具中,无论我在那里键入什么,我都会得到 length: 0

    谢谢你的建议!

    编辑:

    如果需要,我的 JS项目 组件:

    class Project extends Component {
      state = {
        showDetails: false
      };
      constructor(props) {
        super(props);
        this.state = {
           showDetails: false
        };
      }
    
      toggleShowProjects = () => {
        this.setState(prevState => ({
          showDetails: !prevState.showDetails
        }));
      };
    
      render() {
        return (
          <ButtonToolbar>
            <ListGroupItem className="spread">
              {this.props.project.name}
            </ListGroupItem>
            <Button onClick={this.toggleShowProjects} bsStyle="primary">
              Details
            </Button>
            {this.state.showDetails && (
              <ProjectDetails project={this.props.project} />
            )}
          </ButtonToolbar>
        );
      }
    }
    
    export default Project;
    
    2 回复  |  直到 7 年前
        1
  •  3
  •   Dacre Denny    7 年前

    要创建一个“通用”搜索框,您可以执行以下操作:

    class Search extends React.Component {
    
      componentDidMount() {
    
        const { projects, filterProject, onUpdateProjects } = this.props;
        onUpdateProjects(projects);
      }
    
      handleInputChange = (event) => {
    
        const query = event.currentTarget.value;
        const { projects, filterProject, onUpdateProjects } = this.props;
    
        const filteredProjects = projects.filter(project => !query || filterProject(query, project));
    
        onUpdateProjects(filteredProjects);
      };
    
      render() {
        return (
          <form>
            <input onChange={this.handleInputChange} />
           </form>
        );
      }
    }
    

    本修订版 Search 需要一些额外的 props 这样可以根据需要重新使用。除了 projects 道具,你也通过 filterProject 和 onUpdateProjects 由调用代码提供的回调。这个 过滤工程 回调允许您为每个 <Search/> 组件已呈现。这个 更新项目 回调基本上返回项目的“过滤列表”,适用于在父组件(即 <ProjectList/> )

    这里唯一重要的变化是 visibleProjects 到现在的状态 <项目列表/> 从原始列表中跟踪可见(即筛选)项目 项目 传递给 <项目列表/> :

    class Project extends React.Component {
      render() {
        return (
          <div>{ this.props.project }</div>
        );
      }
    }
    
    class ProjectsList extends React.Component {
    
      componentWillMount() {
        
        this.setState({ visibleProjects : [] })
      }
    
      render() {
        return (
          <div>
            <Search projects={this.props.projects} filterProject={ (query,project) => (project == query) } onUpdateProjects={ projects => this.setState({ visibleProjects : projects }) }  />
            <div>
              {this.state.visibleProjects.map(project => {
                return <Project project={project} key={project.id} />;
              })}
            </div>
          </div>
        );
      }
    }
    
    class Search extends React.Component {
      
      componentDidMount() {
        
        const { projects, filterProject, onUpdateProjects } = this.props;
        onUpdateProjects(projects);
      }
      
      handleInputChange = (event) => {
        
        const query = event.currentTarget.value;
        const { projects, filterProject, onUpdateProjects } = this.props;
        
        const filteredProjects = projects.filter(project => !query || filterProject(query, project));
        
        onUpdateProjects(filteredProjects);
      };
    
      render() {
        return (
          <form>
            <input onChange={this.handleInputChange} />
           </form>
        );
      }
    }
    
    ReactDOM.render(
      <ProjectsList projects={[0,1,2,3]} />,
      document.getElementById('react')
    );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.0.0/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.0.0/umd/react-dom.production.min.js"></script>
    <div id="react"></div>
        2
  •  2
  •   Treycos    7 年前

    我假设您的搜索和项目列表组件都有一个包含项目列表的公共父级。 如果是这样,您应该将一个函数传递到您的搜索组件属性中,然后当用户在搜索栏中键入内容时,您的搜索组件将调用该函数。这将帮助父元素决定ProjectsList需要呈现什么:

    handleInputChange = () => {
        this.props.userSearchInput(this.search.value);
        this.setState({
            query: this.search.value
        });
    };
    

    现在,父元素需要包括:

    searchChanged = searchString => {
        const filteredProjects = this.state.projects.filter(project => project.name.includes(searchString))
        this.setState({ filteredProjects })
    }
    

    使用此函数,您将筛选出包含用户在其名称中键入的字符串的项目,然后只需将此数组置于您的状态并将其传递给ProjectsList组件属性

    您可以找到字符串的文档 includes function here

    现在,您可以在创建搜索组件时将此函数添加到该组件的属性中:

    <Search userSearchInput={searchChanged}/>
    

    并将过滤后的数组传递到ProjectsList属性中:

    <ProjectsList projects={this.state.filteredProjects}/>
    

    注意:为了避免使用refs,onchnage函数将向您的函数发送一个“event”对象,其中包含有关用户键入内容的所有内容:

    handleInputChange = event => {
        const { value } = event.target
        this.props.userSearchInput(value);
        this.setState({
            query: value
        });
    };
    

    现在可以从代码中删除引用