简体   繁体   English

选中/取消选中复选框时管理状态-React

[英]Manage State when checkbox is checked/unchecked - React

In my react application a user enters a keyword and gets a list of results. 在我的React应用程序中,用户输入关键字并获得结果列表。 I am trying to implement filters on these results. 我正在尝试对这些结果实施过滤器。 Below is the screenshot of filters. 以下是过滤器的屏幕截图。 在此处输入图片说明

Here is my state 这是我的状态

 class SearchResultsPage extends React.Component{ constructor(props) { super(props); this.state = { results: this.props.location.state.data.results, keyword: this.props.location.state.data.keyword, pageOfItems: [], cities: { 'New York City (NYC)': false, 'Delhi': false, 'Bangkok': false, 'Paris': false, 'Mexico City': false }, topics: { 'Environment': false, 'Crime': false, 'Politics': false, 'Social Unrest': false, 'Infrastructure': false }, languages: { 'Hindi': false, 'English': false, 'Thai': false, 'French': false, 'Spanish': false } }; this.onChangePage = this.onChangePage.bind(this); this.onCityChange = this.onCityChange.bind(this); } 

What I am trying to do is, whenever a checkbox is checked or unchecked I am setting the corresponding checkbox to true/false. 我想做的是,每当复选框处于选中状态或未选中状态时,我都将相应的复选框设置为true / false。 Based on this boolean value of each checkbox I am filtering out the results and then rendering it on the UI. 基于每个复选框的布尔值,我正在过滤results ,然后将其呈现在UI上。 I am able to filter the results when a checkbox is clicked, but I am unable to show all the results back when the checkbox is unchecked. 单击复选框后,我可以过滤结果,但是如果取消选中复选框,则无法显示所有结果。 This is how I am handling when checkbox changes. 复选框更改时,这就是我的处理方式。

 onCityChange(e) { const val = e.target.checked; const name = e.target.name; let updatedCities = Object.assign({},this.state.cities,{[name]: val}); this.setState({ cities: updatedCities, },function () { const filteredCities = []; for (let key in this.state.cities) { if (this.state.cities[key] === true) { filteredCities.push(key) } } const filteredResults = []; this.state.results.forEach((result) => { for (let i = 0; i < filteredCities.length; i++) { if (result.city === filteredCities[i] && result.city != null) { filteredResults.push(result) } } }) console.log(filteredResults.length) if (filteredResults.length > 0) { this.setState({ results: filteredResults }) } }) } 

I know I am not correctly handling the state, what can I do in this situation. 我知道我没有正确处理状态,在这种情况下我该怎么办。 For better reference, here is the complete Search Result code. 为了获得更好的参考,这是完整的搜索结果代码。

 import React from 'react'; import NavigationBar from './NavigationBar'; import SearchPageResultsStyle from "../assets/css/SearchResultsPage.css" import Pagination from './Pagination'; class SearchResultsPage extends React.Component{ constructor(props) { super(props); this.state = { results: this.props.location.state.data.results, keyword: this.props.location.state.data.keyword, pageOfItems: [], cities: { 'New York City (NYC)': false, 'Delhi': false, 'Bangkok': false, 'Paris': false, 'Mexico City': false }, topics: { 'Environment': false, 'Crime': false, 'Politics': false, 'Social Unrest': false, 'Infrastructure': false }, languages: { 'Hindi': false, 'English': false, 'Thai': false, 'French': false, 'Spanish': false } }; this.onChangePage = this.onChangePage.bind(this); this.onCityChange = this.onCityChange.bind(this); } onChangePage(pageOfItems) { // update local state with new page of items this.setState({pageOfItems}); } // setting each city in cities object (city chechboxes which are clicked on UI) to true onCityChange(e) { const val = e.target.checked; const name = e.target.name; let updatedCities = Object.assign({},this.state.cities,{[name]: val}); this.setState({ cities: updatedCities, },function () { const filteredCities = []; for (let key in this.state.cities) { if (this.state.cities[key] === true) { filteredCities.push(key) } } const filteredResults = []; this.state.results.forEach((result) => { for (let i = 0; i < filteredCities.length; i++) { if (result.city === filteredCities[i] && result.city != null) { filteredResults.push(result) } } }) console.log(filteredResults.length) if (filteredResults.length > 0) { this.setState({ results: filteredResults }) } }) } // rendering checkboxes for topics renderCityFilter() { const cities = ['New York City (NYC)','Delhi','Bangkok','Paris','Mexico City'] return cities.map((city,i) => { return ( <div key={i} className={'city-filters'}> <input type="checkbox" name={city} onChange={this.onCityChange} value={this.state.cities[city]}/>&nbsp;&nbsp; <label key={i} style={{fontSize:12}}> {city} </label> </div> ) }) } // rendering checkboxes for topics renderTopicFilter() { const topics = ['Environment','Crime','Politics','Social Unrest','Infrastructure'] return topics.map((topic,i) => { return ( <div key={i}> <input type="checkbox" name={topic} onChange={this.onCityChange} value={this.state.topics[topic]}/>&nbsp;&nbsp; <label key={i} style={{fontSize:12}}> {topic} </label> </div> ) }) } // rendering checkboxes for languages renderLanguageFilter() { const languages = ['Hindi','English','Thai','French','Spanish'] return languages.map((language,i) => { return ( <div key={i}> <input type="checkbox" name={language} onChange={this.onCityChange} value={this.state.languages[language]}/>&nbsp;&nbsp; <label key={i} style={{fontSize:12}}> {language} </label> </div> ) }) } render() { const renderItems = this.state.pageOfItems.map((item, index) => { return ( <div key={index}> <h3 style={{color: '#1a0dab'}} key={index}>{item.text}</h3> <a href={'https://google.com'} key={index}>{item.tweetUrl}</a> <br/> <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>topic: </span>{item.topic}</p> <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>city: </span>{item.city}</p> <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>lang: </span>{item.lang}</p> <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>Hashtags: </span></p> <hr/> </div> ) }); return ( <div> <NavigationBar/> <h4 style={{textAlign:'center', color:'#1a0dab'}}>Showing search results for <span style={{fontWeight:'bold', fontStyle:'Italic'}}>'{this.state.keyword}'</span></h4> <hr/> <div className={'wrap'} style={SearchPageResultsStyle}> <div className={'fleft'}> <h4>City</h4> {this.renderCityFilter()} <hr/> <h4>Topics</h4> {this.renderTopicFilter()} <hr/> <h4>Language</h4> {this.renderLanguageFilter()} <hr/> </div> <div className={'fcenter'}> {renderItems} <Pagination items={this.state.results} onChangePage={this.onChangePage}/> </div> <div className={'fright'}/> </div> </div> ) } } export default SearchResultsPage; 

Try implementing filtered state separately instead of combining with results , take a look at my solution: 尝试单独实现过滤状态,而不是与results结合,看看我的解决方案:

import React from 'react';
import NavigationBar from './NavigationBar';
import SearchPageResultsStyle from "../assets/css/SearchResultsPage.css"
import Pagination from './Pagination';

class SearchResultsPage  extends React.Component{
    constructor(props) {
        super(props);
        this.state = {
            results: this.props.location.state.data.results,
            isFiltered: false, //NEW STATE
            filteredResults: [], //NEW STATE
            keyword: this.props.location.state.data.keyword,
            pageOfItems: [],
            cities: {
                'New York City (NYC)': false,
                'Delhi': false,
                'Bangkok': false,
                'Paris': false,
                'Mexico City': false
            },
            topics: {
                'Environment': false,
                'Crime': false,
                'Politics': false,
                'Social Unrest': false,
                'Infrastructure': false
            },
            languages: {
                'Hindi': false,
                'English': false,
                'Thai': false,
                'French': false,
                'Spanish': false
            }
        };
        this.onChangePage = this.onChangePage.bind(this);
        this.onCityChange = this.onCityChange.bind(this);
    }

    onChangePage(pageOfItems) {
        // update local state with new page of items
        this.setState({pageOfItems});
    }

    // setting each city in cities object (city chechboxes which are clicked on UI) to true
    onCityChange(e) {
        const val = e.target.checked;
        const name = e.target.name;
        let updatedCities = Object.assign({},this.state.cities,{[name]: val});
        this.setState({
            cities: updatedCities,
        },function () {
            const filteredCities = [];
            for (let key in this.state.cities) {
                if (this.state.cities[key] === true) {
                    filteredCities.push(key)
                }
            }
            // CHECK IF SHOULD FILTER
            if (filteredCities.length > 0) {
                const filteredResults = [];
                this.state.results.forEach((result) => {
                    for (let i = 0; i < filteredCities.length; i++) {
                        if (result.city === filteredCities[i] && result.city != null) {
                            filteredResults.push(result)
                        }
                    }
                })
                console.log(filteredResults.length)
                if (filteredResults.length > 0) {
                    this.setState({
                        isFiltered: true,
                        filteredResults: filteredResults
                    })
                }
            } else {
                this.setState({
                    isFiltered: false,
                    filteredResults: []
                })
            }
        })
    }

    // rendering checkboxes for topics
    renderCityFilter() {
        const cities = ['New York City (NYC)','Delhi','Bangkok','Paris','Mexico City']
        return cities.map((city,i) => {
            return (
                <div key={i} className={'city-filters'}>
                    <input
                        type="checkbox"
                        name={city}
                        onChange={this.onCityChange}
                        value={this.state.cities[city]}/>&nbsp;&nbsp;
                    <label key={i} style={{fontSize:12}}>
                        {city}
                    </label>
                </div>

            )
        })
    }

    // rendering checkboxes for topics
    renderTopicFilter() {
        const topics = ['Environment','Crime','Politics','Social Unrest','Infrastructure']
        return topics.map((topic,i) => {
            return (
                <div key={i}>
                    <input
                        type="checkbox"
                        name={topic}
                        onChange={this.onCityChange}
                        value={this.state.topics[topic]}/>&nbsp;&nbsp;
                    <label key={i} style={{fontSize:12}}>
                        {topic}
                    </label>
                </div>

            )
        })
    }

    // rendering checkboxes for languages
    renderLanguageFilter() {
        const languages = ['Hindi','English','Thai','French','Spanish']
        return languages.map((language,i) => {
            return (
                <div key={i}>
                    <input
                        type="checkbox"
                        name={language}
                        onChange={this.onCityChange}
                        value={this.state.languages[language]}/>&nbsp;&nbsp;
                    <label key={i} style={{fontSize:12}}>
                        {language}
                    </label>
                </div>

            )
        })
    }

    render() {

        const renderItems = this.state.pageOfItems.map((item, index) => {
            return (
                <div key={index}>
                    <h3 style={{color: '#1a0dab'}} key={index}>{item.text}</h3>
                    <a href={'https://google.com'} key={index}>{item.tweetUrl}</a>
                    <br/>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>topic: </span>{item.topic}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>city: </span>{item.city}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>lang: </span>{item.lang}</p>
                    <p><span style={{fontWeight:'bold', textColor:'#6a6a6a'}} key={index}>Hashtags: </span></p>
                    <hr/>
                </div>
            )
        });

        return (
            <div>
                <NavigationBar/>
                <h4 style={{textAlign:'center', color:'#1a0dab'}}>Showing search results for <span style={{fontWeight:'bold', fontStyle:'Italic'}}>'{this.state.keyword}'</span></h4>
                <hr/>
                <div className={'wrap'} style={SearchPageResultsStyle}>
                    <div className={'fleft'}>
                        <h4>City</h4>
                        {this.renderCityFilter()}
                        <hr/>
                        <h4>Topics</h4>
                        {this.renderTopicFilter()}
                        <hr/>
                        <h4>Language</h4>
                        {this.renderLanguageFilter()}
                        <hr/>
                    </div>
                    <div className={'fcenter'}>
                        {renderItems}
                        {//CHECK SHOULD RENDER RESULTS OR FILTEREDRESULTS}
                        <Pagination items={this.state.isFiltered ? this.state.filteredResults : this.state.results} onChangePage={this.onChangePage}/>
                    </div>
                    <div className={'fright'}/>
                </div>
            </div>
        )
    }
}

export default SearchResultsPage;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在react native应用程序中(已选中或未选中)保存/保持CheckBox的状态/为复选框提供了无效的prop - Save / keep the state of the CheckBox in react native application (checked or unchecked ) / Invalid prop supplied to checkbox 如何在反应中实现复选框(选中和未选中的功能)? - how to implement checkbox in react (checked and unchecked functionality)? HandleCheckBox 反应选中和未选中,将列表放入 state - HandleCheckBox react checked and unchecked , get a list into a state 在iCheck的复选框上显示和隐藏另一个复选框处于选中和未选中状态 - Show And Hide Another Checkbox on iCheck's checkbox checked and unchecked state 选中/取消选中复选框时切换文本 - Toggle text when checkbox is checked/unchecked 选中和取消选中复选框时更改跨度值 - changing span value when checkbox is checked and unchecked 取消选中复选框时,从收音机中删除“选中” - Remove “checked” from radio when a checkbox is unchecked 选中/取消选中时填充/清除数组 - Populate/clear array when checkbox checked/unchecked 选中/取消选中复选框时更改变量值 - Change variable value when checkbox is checked/unchecked 选中/取消选中复选框时启用/禁用下拉菜单 - Enable/disable dropdowns when checkbox checked/unchecked
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM