Reputation: 41
I am working on some reactjs project that will show data based on user query. User can type and filtered data by checkbox. It working properly actually, user type something in search bar and record are fetching data correctly. The problem is when user use check box to filter some data, the exact data show up but when they remove/uncheck the checkbox, the filtered data is not show up, instead it show the whole data. I want that, when user remove/uncheck the checkbox from that data they type, it show back the original data that user type. I am sorry if my language is a little bit difficult to understand. I will provide my code please have a look and help me to figure out if I made some mistake, also please tell me what is the best practice to fix this problem. I am beginner to React and does not have much knowledge to fix this problem . Thanks
import React from 'react';
import logo from './logo.svg';
import { Dropdown } from 'semantic-ui-react'
import './App.css'
import DropdownCheckbox from './components/dropdownCheckbox/dropdownCheckbox';
class App extends React.Component {
constructor(props) {
super(props)
this.state = {
furnitureStyles: [],
products: [],
checkedFS: [],
checkedDT: [],
searchFilt: "",
filteredProduct: []
};
};
async onDropdownChange(val){
await this.setState({
checkedFS: val
})
await this.filteredFurnitureStyle()
}
fetchData(){
fetch('http://www.mocky.io/v2/5c9105cb330000112b649af8')
.then( response => {
if(response.status === 200){
return response.json()
}
})
.then(responseJson => {
this.setState({
furnitureStyles: responseJson.furniture_styles,
products: responseJson.products,
filteredProduct: responseJson.products
})
})
}
componentDidMount(){
this.fetchData()
}
loadingPage(){
return(
<div>
Please Wait ...
</div>
)
}
regexDesc(value){
return value.replace(/(?<=^.{115}).*/, " ...")
}
async filteringFunc(e){
const { checkedDT, checkedFS, searchFilt, products, filteredProduct } = this.state
if(e.target.value !== "") {
let search = products.filter(product => product.name.toLowerCase().indexOf(e.target.value.toLowerCase()) !== -1)
this.setState({
filteredProduct : search
})
} else if(e.target.value === ""){
this.setState({
filteredProduct: products
})
}
}
async onDropdownChange(val){
await this.setState({
checkedFS: val
})
await this.filteredFurnitureStyle()
}
filteredFurnitureStyle = () => {
const { filteredProduct, checkedFS, products } = this.state
if(checkedFS.length > 0) {
let search = filteredProduct.filter(product => (
checkedFS.findIndex(element => product.furniture_style.indexOf(element) !== -1) !== -1
))
this.setState({
filteredProduct: search
})
} else {
this.setState({
filteredProduct: products
})
}
}
render(){
const { furnitureStyles, products, checkedDT, checkedFS, filteredProduct } = this.state
return (
<div className="App">
<header>
<div className="search-section">
<input type="search"
placeholder="Search Furniture ..."
className="search-input"
onChange={(e)=>this.filteringFunc(e)}
/>
</div>
<div className="dropdown-section"
>
{furnitureStyles.length > 0 ? (
<React.Fragment>
<DropdownCheckbox
style={{margin:"0 24px"}}
defaultSelected="Furniture Style"
options={furnitureStyles}
onChange={(val)=>this.onDropdownChange(val)}
/>
<DropdownCheckbox
style={{margin:"0 24px"}}
defaultSelected="Delivery Time"
options={["1 week","2 weeks", "1 Month", "more..."]}
onChange={val=>this.setState({
checkedDT: val
})}
/>
</React.Fragment>) : "Loading"
}
</div>
</header>
<div id="section2">
<div className="card-section">
{products.length > 0 &&
filteredProduct.map(product => {
return (
<div className="ui cards flexing">
<div className="ui fluid card content">
<div className="card-header">
<h4>
{product.name}
</h4>
<span>
IDR {product.price}
</span>
</div>
<div>
<span>
{this.regexDesc(product.description)}
</span>
<div>
<ul className="furniture-styles">
{product.furniture_style.map(style => {
return (
<li>{style}</li>
)
})}
</ul>
</div>
</div>
<div>
<span>{product.delivery_time} {product.delivery_time > 1 ? "days" : "day"}</span>
</div>
</div>
</div>
)
})
}
</div>
</div>
</div>
);
}
}
export default App;
Upvotes: 0
Views: 64
Reputation: 10873
await this.setState
isn't gonna work. If you need to call a function after updating a state, use setState
's callback function:
onDropdownChange = (val) => {
this.setState({
checkedFS: val
}, this.filteredFurnitureStyle) // Use callback
}
Upvotes: 2