带输入的ReactJS即时搜索

时间:2018-12-16 19:19:00

标签: javascript reactjs

我正在做我的第一个React项目。我是JS,HTML,CSS甚至网络应用程序编程的新手。

我要执行的操作是搜索输入标签。现在看起来像这样:

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;

...和ProjectList.js显示Project.js

Search.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属性。您能否告诉我如何根据文本标签中的输入动态地对Search.js组件进行编码,以动态更改显示projects?例如,仅return Project,如果输入中的文本匹配(我想动态搜索它,当我开始输入m ...时,它将显示所有从m开始的项目,等等)。

如何正确输入“搜索”?如何使其具有通用性,例如在另一个对象列表中进行搜索?以及如何从“搜索”返回到“父级”组件?

现在,无论我在哪里键入React开发工具,我都会得到length: 0

感谢您的任何建议!

编辑:

如果需要,我的Project.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 个答案:

答案 0 :(得分:3)

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

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道具之外,您还传递filterProjectonUpdateProjects回调,它们由调用代码提供。 filterProject回调允许您为呈现的每个<Search/>组件提供自定义过滤逻辑。 onUpdateProjects回调基本上返回项目的“过滤列表”,适合在父组件(即<ProjectList/>)中呈现。

这里唯一的重大变化是在状态visibleProjects中添加了<ProjectList/>,该状态跟踪传递给{{的原始projects列表中的可见(即过滤)项目。 1}}:

<ProjectList/>
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')
);

答案 1 :(得分:2)

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

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组件props

您可以找到字符串includes function here

的文档

现在,您可以在创建搜索组件时将其添加到搜索组件的道具中。

<Search userSearchInput={searchChanged}/>

并将经过过滤的数组传递到您的ProjectsList道具中:

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

旁注:尽量避免使用引用,onCHnage函数将向您的函数发送一个“事件”对象,其中包含有关用户键入内容的所有内容:

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

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