Reputation: 274
Search function is working perfectly fine in the console log but when I try to assign that value to rows which is a state. So I setState the rows inside the setState in searchHandler. I know I'm making a mistake but I don't know how to rectify it. OMIT THE UNDECLARED STATES, MINIFIED THE CODE TO WHAT'S NEEDED
function searchingFor(searchingTerm) {
return function(x){
// console.log("searching",x);
return x.name.toLowerCase().includes(searchingTerm.toLowerCase())|| false;
}
}
class Main extends React.Component{
componentWillMount(){
this.props.fetchTopicsTableContent(this.state.sortBy,'ASC',0,this.props.match.params.CategoryName).then(result=> (this.setState({rows:result.payload.data})))
this.props.countTableContent(this.props.match.params.CategoryName).then(result=>(this.setState({count:result.payload})));
}
constructor(props){
super(props);
this.state={
rows:"",
searchTerm:"",
items:""
}
}
onSubmit(values){
values.preventDefault();
}
onSearchHandler(e){
this.setState({searchTerm:e.target.value},()=>{
{this.state.rows.filter(searchingFor(this.state.searchTerm)).map(item=>{
console.log(item);
//this.setState({rows:item})
})}
})
}
render(){
return(
<div>
<h3>Topics</h3>
<hr/>
<div>
<form onSubmit={this.onSubmit.bind(this)}>
<input type="text"
className="searchBar"
value={this.state.searchTerm}
onChange={this.onSearchHandler.bind(this)}
/>
</form>
</div>
</div>
)
}
Upvotes: 0
Views: 3133
Reputation: 139
Your logic is fine, but the code looks clumsy.I refactored the code so that only necessary logic is present and instead of bind
use arrow functions.
Here, try this code on codeSandbox
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
constructor(props){
super(props);
this.state = {
rows: ["asd", "bsd", "csd", "dsd", "esd"],
items: []
}
}
onSearchHandler = (e) => {
this.setState({ items: this.state.rows.filter(str => str.toLowerCase().includes(e.target.value.toLowerCase()))})
}
render(){
return (
<div>
<h3>Topics</h3>
<input type="text"
className="searchBar"
onChange={(e) => this.onSearchHandler(e)}/>
<p>{this.state.items.join('\n')}</p>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
Upvotes: 0
Reputation: 479
Okay so lets start with binding your functions in the constructor, not in the markup, clean things up :P
Next, i'm not sure you understand how setting state works as your function goes against it's basic use. You are correctly setting the first state and using the callback (Because it takes time for state to actually be set) which is great. The callback function it's where it goes downhill.
Your mapping function is loading up several setState calls instantly, for each one console.log() will run successfully, but only one of the setStates will actually take effect. On top of that, even if it did work, your rows
state will only have a single item. Lets try this:
onSearchHandler(e){
this.setState(prevState => {
return {
rows: prevState.rows.filter(searchingFor(e.target.value)),
searchTerm: e.target.value,
}
});
}
That will get you what I assume is the desired result... you should only ever do one setState at a time, unless you are waiting for the callback on each one, because you can't be sure each one will complete before the next.
Upvotes: 2