![](/img/trans.png)
[英]Save / keep the state of the CheckBox in react native application (checked or unchecked ) / Invalid prop supplied to checkbox
[英]Manage State when checkbox is checked/unchecked - React
在我的React應用程序中,用戶輸入關鍵字並獲得結果列表。 我正在嘗試對這些結果實施過濾器。 以下是過濾器的屏幕截圖。
這是我的狀態
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); }
我想做的是,每當復選框處於選中狀態或未選中狀態時,我都將相應的復選框設置為true / false。 基於每個復選框的布爾值,我正在過濾results
,然后將其呈現在UI上。 單擊復選框后,我可以過濾結果,但是如果取消選中復選框,則無法顯示所有結果。 復選框更改時,這就是我的處理方式。
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 }) } }) }
我知道我沒有正確處理狀態,在這種情況下我該怎么辦。 為了獲得更好的參考,這是完整的搜索結果代碼。
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]}/> <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]}/> <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]}/> <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;
嘗試單獨實現過濾狀態,而不是與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]}/>
<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]}/>
<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]}/>
<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.