【问题标题】:ReactJS Search and Dropdown filter synchronisedReactJS 搜索和下拉过滤器同步
【发布时间】:2019-01-04 13:01:18
【问题描述】:

我想要同步的 ReactJS 页面上有一个 搜索 和 下拉 选项。这意味着每当您从下拉选项中选择一个元素时,屏幕上的元素只会显示选定的过滤器。

搜索输入当前有效,但我遇到了选择选项问题。我找到了一个选择过滤器的工作示例 (this one here),但我在调整它以适应我的解决方案时遇到了问题。

我认为这里的这个功能是过滤数据的主要功能,但我很不确定:

changeOption: function(type, e) {
    var val = e.target.value;
    this.props.changeOption(val, type);
  }

如何根据选择选项值过滤数据?

这是我的代码的 JSFiddle 示例:JS Fiddle Example

【问题讨论】:

  • 1.将onChange={this.handleChange} 添加到您的<select>。它现在可能已经工作了,但是您需要修复另外两个小错误:在您的渲染中,您需要 text = data.filter(...(您正在过滤 text),在您的主 JSX 中,您需要 data.map 的选项:@ 987654323@
  • @ChrisG 现在可以使用了,谢谢。我只是想问一下,为什么您将 text 更改为 data 作为选项?

标签: javascript reactjs


【解决方案1】:

您必须将所选值存储在您所在州的select 标记中,并根据它过滤您的输出:

状态:

        this.state = {
            isLoading: false,
            data: [],
            searchString: '',
            roleFilter: null
        };

触发功能:

    changedRole = ev => {
        this.setState({ roleFilter: ev.target.value })
    }

更改事件:

<select className="category-select" name="categories" onChange={this.changedRole}>

过滤:

    {text.filter(info => roleFilter ? info.role.includes(roleFilter) : true).map(info => (
                    <div className="display">
                        <span className="role">Role: {info.role}</span><span>, Salary: {info.salary}</span>
                    </div>
                ))}

完整的工作代码:

    class Hello extends React.Component {
    
        constructor(props) {
            super(props);
            this.state = {
                isLoading: false,
                data: [],
                searchString: '',
                roleFilter: null
            };
        }
    
        componentDidMount() {
            this.fetchData();
        }
    
        handleChange = e => {
            this.setState({ searchString: e.target.value.trim().toLowerCase() });
        }
    
        fetchData() {
            fetch("https://api.myjson.com/bins/kr5kk")
                .then(response => response.json())
                .then(json => {
                    this.setState({
                        isLoaded: true,
                        data: json
                    });
                })
                .catch(error => console.log("parsing failed", error));
        }
    
        changedRole = ev => {
            this.setState({ roleFilter: ev.target.value })
        }
    
        render() {
            var { isLoaded, data, roleFilter, searchString } = this.state;
            let text = data;
            if (searchString) {
                text = text.filter(info => info.role.toLowerCase().match(searchString));
            }
            return (
                <div>
                    <input type="text" id="searchbar" value={searchString} onChange={this.handleChange}
                        placeholder="Search by Role" name="device">
                    </input>
    
                    <select className="category-select" name="categories" onChange={this.changedRole}>
                        <option value={''}></option>
                        {text.map(info => (
                            <option value={info.role}>{info.role}</option>
                        ))}
                    </select>
                    {text.filter(info => roleFilter ? info.role.includes(roleFilter) : true).map(info => (
                        <div className="display">
                            <span className="role">Role: {info.role}</span><span>, Salary: {info.salary}</span>
                        </div>
                    ))}
                </div>
            );
        }
    }
    
    ReactDOM.render(
        <Hello name="World" />,
        document.getElementById('container')
    );
.display{
  background-color:#b6d0f9;
  margin-top:10px;
  padding-top:10px;
  padding-bottom:10px;
}
.role{
  color:red;
}
#searchbar{
  margin-right:150px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.3.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.3.1/umd/react-dom.production.min.js"></script>
<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

【讨论】:

  • 您检查过您的代码吗?使用下拉菜单后,如果不重新加载页面,您将无法访问完整的元素。
  • 是的,我显然测试了我的代码,你从来没有说过你想回到完整的列表。我用一个额外的空白选项编辑了我的答案,这解决了你的问题
【解决方案2】:

您需要在 select 上添加一个事件侦听器,以便在值更改时捕获它。例如:

<select
  onChange={ () => this.handleSelectChange() }
  className="category-select" name="categories"
>
  {text.map(info => (
    <option value={info.role}>{info.role}</option>
  ))}
</select>

然后你需要将select的当前值保存在组件的状态中,并根据它过滤列表,与搜索相同。

见this。可能是重复的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-08
    • 2023-03-14
    相关资源
    最近更新 更多