I have the following code:
Parent component:
class App extends Component {
state = {
colors: []
};
async componentDidMount() {
const fetched = await fetch("./response.json");
const fetchedJson = await fetched.json();
const res = fetchedJson.colors;
this.setState({
colors: res
});
}
filterItems = (name) => {
const lowerCaseName = name.toLowerCase();
const newColors = [...this.state.colors];
const res = newColors.filter((color) => {
const lowerCaseColorName = color.name.toLowerCase();
return lowerCaseColorName.includes(lowerCaseName);
});
this.setState({
colors: res
});
};
render() {
const { colors } = this.state;
return (
<div>
<InputText filterItems={this.filterItems} />
<AllData colors={colors} />
</div>
);
}
}
And this is my Child component:
class Filter extends Component {
state = {
inputVal: ""
};
onChange = (e) => {
this.setState({
inputVal: e.target.value
});
this.props.filterItems(e.target.value);
};
render() {
return (
<form onSubmit={this.onSubmit}>
<input
type="text"
onChange={this.onChange}
value={this.state.inputVal}
/>
</form>
);
}
}
export default Filter;
There's also another child component called AllData
but its job is just displaying out data and put styling on it, so I'm not including it here.
Currently the data displayed are just:
Fire Dragon
Water Horse
Earth Bird
Wood Dog
Wind Cat
Here are my questions:
filter
function works fine when I type in a word into the search box in filter. However, when I backtrack and remove a previous character down to the whole input string, the res
array doesn't return its whole original arrays but instead retains the result of the filter only when I type more.Ex:
When I type in the string "cat", res
becomes: [{name: "Wind Cat", id: 5}
However I remove that string by backtracking on the keyboard, res
is still at [{name: "Wind Cat", id: 5}
. Why is it not going back to returning all of the items, and how do I fix this?
onChange = (e) => {
this.setState({
inputVal: e.target.value
});
this.props.filterItems(e.target.value);
};
However, if I change it to:
this.props.filterItems(this.state.inputVal);
and console.log(name)
out in the parent component at filterItems
, every time I type in a string, it seems like the console.logged name
only display the character before.
Ex:
If I type in the string c
-> name
would be "" (empty)
If I type in the string ca
-> name
would be c
Why is this happening?
class App extends Component {
state = {
colors: [],
filtered: [],
};
async componentDidMount() {
const fetched = await fetch("./response.json");
const fetchedJson = await fetched.json();
const res = fetchedJson.colors;
this.setState({
colors: res
});
}
filterItems = (name) => {
const lowerCaseName = name.toLowerCase();
const newColors = [...this.state.colors];
const filtered = newColors.filter(color => {
const parts = color.split(' ').map(part => part.toLowerCase());
return parts.reduce((carry, part) => {
return carry ? carry : part.startsWith(lowerCaseName);
}, false);
});
this.setState({
filtered,
});
};
render() {
const { colors, filtered } = this.state;
return (
<div>
<InputText filterItems={this.filterItems} />
<AllData colors={filtered ? filtered : colors} />
</div>
);
}
}