【问题标题】:How to filter values for multiple data using reactjs?如何使用 reactjs 过滤多个数据的值?
【发布时间】:2020-06-10 20:29:21
【问题描述】:

我是新手,想为对象中的多个数据创建搜索过滤器。我试过过滤单个数据,代码如下:

    var {Data, search} =this.state;
            search = this.state.search.trim().toLowerCase();
        if (search.length > 0) {
          Data= Data.filter(function(i) {
            return i.firstName.toLowerCase().match( search );

          });
        }

效果很好,但仅适用于 firstName。但我的目标是同时过滤姓氏、位置和技能。

代码如下:

export default class DataView extends React.Component {
  constructor() {
    super();
    this.state = {
      Data: [],
      search: ""
    };
  }
  componentDidMount() {
    this.fetchData();
  }
  fetchData() {
    fetch("api/Profile")
      .then(response => response.json())
      .then(data => {
        this.setState({
          Data: data.item1
        });
      });
  }
  handleSearch = e => {
    this.setState({ search: e.target.value });
  };

  render() {
    var { Data, search } = this.state;
    search = this.state.search.trim().toLowerCase();
    if (search.length > 0) {
      Data = Data.filter(function(i) {
        return i.firstName.toLowerCase().match(search);
      });
    }

    return (
      <div>
        <Segment className="p_segment">
          <Input
            icon="search"
            placeholder="Search..."
            className="a_Search"
            value={this.state.search}
            onChange={this.handleSearch}
          />
        </Segment>

        <Container className="p_view">
          {Data.map(View => {
            return (
              <Grid key={View.id}>
                <Grid.Row className=" p_header">
                  <Checkbox className="p_checkbox" />
                  <Header>
                    {" "}
                    {View.firstName} {View.lastName}{" "}
                  </Header>
                </Grid.Row>
                <Divider className="p_divider" />
                <Grid.Row>
                  <Icon name="marker" /> {View.location}
                  <Divider className="p_divider" />
                </Grid.Row>
                <Grid.Row>
                  <Grid.Column>
                    <div>
                      <div className="g_column">
                        {View.skillset.map(data => {
                          return (
                            <Label className="c_label">{data.skill}</Label>
                          );
                        })}
                      </div>
                    </div>
                  </Grid.Column>
                </Grid.Row>
              </Grid>
            );
          })}
        </Container>
      </div>
    );
  }
}

任何人都可以在这个查询中帮助我吗?

【问题讨论】:

  • 技能组是不是一个数组,你也想在这个数组中搜索?
  • 你能创建工作样本吗??
  • @Agney - 是的,正确。

标签: javascript reactjs


【解决方案1】:

你可以简单地做一个 OR 语句

return i.firstName.toLowerCase().match( search ) || i.skills.toLowerCase().match( search ) || i.location.toLowerCase().match( search );

或者如果你想搜索整个对象

return JSON.stringify(i).toLowerCase().match(search);

【讨论】:

  • @Sandhya :接受上述答案是一个非常糟糕的选择 - 如果您需要检查 5、10、15 个道具,第一个建议的解决方案将变成 OR 链条件的愚蠢块;第二个选项是完全错误的——它不仅会匹配属性值,还会匹配属性名称,因此,每当您搜索一些与您的键名部分匹配的字符串时,您将获得整个数组而不是正确匹配。我什至不说性能(但即使对于上述解决方案may result 的 3 条记录,性能损失为 20%,想象一下 100 条记录,1000 条......
【解决方案2】:

如果对象值之间不区分大小写的部分匹配是您所追求的,您可以简单地将Object.values() 提取到一个数组中,并以与您类似的方式使用Array.prototype.some()Array.prototype.filter()做了:

const stateData = [{
          firstName: 'Stephen',
          lastName: 'Smith',
          location: 'Johannesburg',   //match by location
          skills: 'golf'
        },{
          firstName: 'George',
          lastName: 'Washington',
          location: 'Philadelphia',
          skills: 'majohng'           //match by skills
        },{
          firstName: 'Dummy',
          lastName: 'Dummyson',
          location: 'Dummywille',
          skills: 'dummy'
      }],
      searchString = 'jo',
      
      searchResult = stateData.filter(record => 
        Object
          .values(record)
          .some(prop => 
            prop
              .toLowerCase()
              .includes(searchString.toLowerCase())
           )
       )
        
console.log(searchResult)
.as-console-wrapper{min-height:100%;}

【讨论】:

    【解决方案3】:

    一些符号。

    var { Data, search } = this.state; // don't use var
        search = this.state.search.trim().toLowerCase(); // don't do mutation
        if (search.length > 0) {
          Data = Data.filter(function(i) { // don't do mutation
            return i.firstName.toLowerCase().match(search);
          });
        }
    
    1. result 添加到状态。
    2. 使用componentDidUpdate
    3. 检查search 字段是否已更改。
    4. 做过滤。
    5. 如果search 字段为空,则重置result

    import React from "react";
    
    export default class DataView extends React.Component {
      constructor(props) {
        super(props);
        this.state = {
          data: [],
          search: "",
          result: [], // [1]
        };
      }
    
      componentDidMount() {
        this.fetchData();
      }
      
      componentDidUpdate(prevProps, prevState) { // [2]
        const { search: prevSearch } = prevState;
        const { search: nextSearch, data } = this.state;
        
        if (prevSearch !== nextSearch) { // [3]
          const trimed = nextSearch.trim().toLowerCase();
          const result = nextSearch.length > 0
          ? data.filter(({ firstName, lastName }) => ( // [4]
            `${firstName} ${lastName}`.toLowerCase().includes(trimed)
          ))
          : []; // [5]
          
          this.setState({ result });
        }
      }
    
      fetchData() {
        fetch("api/Profile")
          .then(response => response.json())
          .then(({ item1 }) => {
            this.setState({ data: item1 });
          });
      }
      handleSearch = (e) => {
        this.setState({ search: e.target.value });
      };
    
      render() {
        const { data, search, result } = this.state;
    
        return (
          <div>
            <Segment className="p_segment">
              <Input
                icon="search"
                placeholder="Search..."
                className="a_Search"
                value={search}
                onChange={this.handleSearch}
              />
            </Segment>
    
            <Container className="p_view">
              {result.map((view) => {
                const {
                  id,
                  firstName,
                  lastName,
                  location,
                  skillset,
                } = view;
                
                return (
                  <Grid key={id}>
                    <Grid.Row className=" p_header">
                      <Checkbox className="p_checkbox" />
                      <Header>
                        {` ${firstName} ${lastName} `}
                      </Header>
                    </Grid.Row>
                    <Divider className="p_divider" />
                    <Grid.Row>
                      <Icon name="marker" /> {location}
                      <Divider className="p_divider" />
                    </Grid.Row>
                    <Grid.Row>
                      <Grid.Column>
                        <div>
                          <div className="g_column">
                            {skillset.map(({ skill }) => (
                              <Label className="c_label">{skill}</Label>
                            ))}
                          </div>
                        </div>
                      </Grid.Column>
                    </Grid.Row>
                  </Grid>
                );
              })}
            </Container>
          </div>
        );
      }
    }
    <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>

    【讨论】:

      猜你喜欢
      • 2014-08-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      • 1970-01-01
      • 1970-01-01
      • 2019-12-25
      • 2017-04-02
      相关资源
      最近更新 更多