当React中过滤列表为空时如何显示消息

时间:2018-11-13 13:49:18

标签: javascript reactjs

我正在一个项目中,如果用户在搜索输入中键入不匹配的字母,则尝试显示div内容为找不到结果的内容列表中的任何过滤器。我尝试使用这种类似的解决方案作为参考:React: How to show message when result is zero in react,但没有成功。

这是我的代码的片段,是到目前为止我尝试过的一种解决方案:

class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      searchQuery: ""
    };
  }

  handleSearchQuery = event => {
    this.setState({ searchQuery: event.target.value });
  };

  resetInputField = () => {
    this.setState({ searchQuery: "" });
  };

  render() {
    const { subContent, type, options, label } = this.props;
    const { searchQuery } = this.state;
    return (
      <div
        style={{
          display: "grid",
          alignItems: "center",
          width: "100%",
          margin: "0 0 24px 0",
          fontSize: "14px"
        }}
      >
        <div style={sx.rangeInputContainer}>
          <input
            style={sx.rangeInputLong}
            type="text"
            placeholder={placeholderText}
            onChange={this.handleSearchQuery}
            value={searchQuery}
          />
        </div>
        <div>
          {options
            .filter(
              option =>
                option.label
                  .toLowerCase()
                  .includes(searchQuery.toLowerCase()) || !searchQuery
            )
            .map((option, index) => {
              return option.label.length !== 0 ? (
                <div key={index} style={sx.filterOption}>
                  <SquareCheckbox
                    type="checkbox"
                    id={"multiSelectCheckbox-" + option.label}
                  />
                  <label
                    style={{ color: "#FFF" }}
                    htmlFor={"multiSelectCheckbox-" + option.label}
                  >
                    {option.label}
                  </label>
                </div>
              ) : (
                <div
                  key={index}
                  style={{
                    display: "flex",
                    alignItems: "center",
                    marginTop: "16px"
                  }}
                >
                  <img
                    style={{ width: "20px", cursor: "pointer" }}
                    src={resetIconSVG}
                    onClick={this.resetInputField}
                  />
                  <div style={{ marginLeft: "16px" }}>
                    No results found for {searchQuery}
                  </div>
                </div>
              );
            })}
        </div>
      </div>
    );
  }
}

以下是选项的摘要,位于我的父组件中:

this.state = {
        filters: [


            {
                label: 'Materials',
                type: FILTER_TYPE.MULTI_SELECT,
                expandedHandle: ()=> {  
                this.handleExpandedToggle('Materials'); },
                options:materials,
                expanded:false,
            },
            {
                label: 'Status',
                type: FILTER_TYPE.SELECT,
                expandedHandle: ()=> {  this.handleExpandedToggle('Status'); 
             },
                options: status,
                expanded:false,
            },


        ],
    };

我正在使用的虚拟.json数据:

export const materials = [
{ value: 'brass', label: 'brass' },
{ value: 'chrome', label: 'chrome' },
{ value: 'ceramic', label: 'ceramic' },
{ value: 'glass', label: 'glass' },
{ value: 'concrete', label: 'concrete' },

];

export const status = [
{ value: 'Show All', label: 'Show All' },
{ value: 'Enabled Only', label: 'Enabled Only' },

];

2 个答案:

答案 0 :(得分:1)

就像您在filter方法的返回值内使用三元运算符一样。我会将过滤器放入变量

const filteredOptions = options.filter(option => option.label.toLowerCase().includes(searchQuery.toLowerCase()) || !searchQuery).map((option, index) => {
  return option.label.length !== 0 ? <div key={index} style={sx.filterOption}>
    <SquareCheckbox type='checkbox' id={'multiSelectCheckbox-' + option.label} />
    <label style={{ color: '#FFF' }} htmlFor={'multiSelectCheckbox-' + option.label}> {option.label} </label>
  </div> })

,然后在渲染器中使用三进制检查数组的长度

render {
 return (
  {filteredOptions.length > 0 ? filteredOptions : <div style = {{ marginLeft: '16px' }}>No results found for { searchQuery }</div>}
  )
}

答案 1 :(得分:1)

我对您的options数据进行了假设,希望对您有所帮助(我简化了代码)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      searchQuery: ''
    };
  }
  handleSearchQuery = event => {
    this.setState({ searchQuery: event.target.value });
  };
  resetInputField = () => {
    this.setState({ searchQuery: '' });
  };
  render() {
    const { searchQuery } = this.state;
    const options = [
      { label: 'react' },
      { label: 'angular' },
      { label: 'vue' }
    ];
    const filteredOptions = options.filter(
      option =>
        option.label.toLowerCase().includes(searchQuery.toLowerCase()) ||
        !searchQuery
    );
    return (
      <div>
        <div>
          <input
            type="text"
            onChange={this.handleSearchQuery}
            value={searchQuery}
          />
        </div>
        <div>
          {filteredOptions.length > 0 ? (
            filteredOptions.map((option, index) => {
              return <div key={index}>{option.label}</div>;
            })
          ) : (
            <div>
              No results found for {searchQuery}
            </div>
          )}
        </div>
      </div>
    );
  }
}
ReactDOM.render(<App />, document.getElementById('root'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="root"></div>