looking for advice on how to have one button that when clicked will switch the list of items to the alphabetized list of items and back when clicked again and so on. as of right now when i click the button it will show the alphabetized list but its just rendering on top of the original list already showing. not really sure on where to go from here
class MenuItems extends Component {
state = {
sortedItems: []
}
handleclick = (item) => {
this.props.deleteMenuItem(item.id);
}
menuSort = () => {
const ogList = [...this.props.menuItems]
let sortedList = ogList.sort((a, b) => a.name.localeCompare(b.name));
this.setState({sortedItems: sortedList})
};
render(){
return (
<div>
<button onClick={this.menuSort}>filter a to z</button>
{this.state.sortedItems.map((item) =>(
<li class="list" key={item.id}>
{item.name}
<br></br>
{item.body}
<br></br>
<img src={item.image}></img>
<br></br>
<button id={item.id} onClick={() => this.handleclick(item)}>delete </button>
</li>
))}
{this.props.menuItems.map((item) =>(
<li class="list" key={item.id}>
{item.name}
<br></br>
{item.body}
<br></br>
<img src={item.image}></img>
<br></br>
<button id={item.id} onClick={() => this.handleclick(item)}>delete </button>
</li>
))}
</div>
)
}
}
export default connect(null, {deleteMenuItem})(MenuItems)```
CodePudding user response:
You correctly thought to keep the sorted version in the state. But you have to somehow instruct the component to render the original list or the sorted one.
So you could add a flag in the state
to specify which one you want.
You could also set the sorted list in the componentDidMount lifecycle event, and updated it whenever the menuItems
change through the componentDidUpdate
lifecycle event.
So something like
state = {
sortedItems: [],
showSorted: false
};
toggleSort = () => {
this.setState(({ showSorted }) => ({
showSorted: !showSorted
}));
};
updateSortedItems() {
const sorted = [...this.props.menuItems].sort((a, b) =>
a.name.localeCompare(b.name)
);
this.setState({
sortedItems: sorted
});
}
componentDidMount() {
this.updateSortedItems();
}
componentDidUpdate(prevProps) {
if (this.props.menuItems !== prevProps.menuItems) {
this.updateSortedItems();
}
}
and in your render method
let itemsToShow = this.props.menuItems;
if (this.state.showSorted) {
itemsToShow = this.state.sortedItems;
}
and use the itemsToShow
when you want to display them
{itemsToShow.map((item) => (
Full working example at https://codesandbox.io/s/elated-heyrovsky-m3jvv
CodePudding user response:
The first render state will be store props valus and to then when we click on toggle button then only sort the array. We can check sort or not by using to toggle state. Final code like this
class MenuItems extends Component {
state = {
sortedItems: this.props.menuItems.sort((a, b) => a.name.localeCompare(b.name)),
toggle:false,
}
handleclick = (item) => {
this.props.deleteMenuItem(item.id);
}
menuSort = () => {
const ogList = [...this.props.menuItems]
let sortedList = ogList.sort((a, b) => a.name.localeCompare(b.name));
this.setState({sortedItems: sortedList})
};
render(){
return (
<div>
<button onClick={()=>{
if(this.state.toggle==false){
this.setState({toggle: ture})
this.menuSort();
}
else{
this.setState({toggle: false})
this.setState({sortedItems: this.props.menuItems})
}
}>filter a to z</button>
{this.state.sortedItems.map((item) =>(
<li class="list" key={item.id}>
{item.name}
<br></br>
{item.body}
<br></br>
<img src={item.image}></img>
<br></br>
<button id={item.id} onClick={() => this.handleclick(item)}>delete </button>
</li>
))}
{this.state.sortedItems.map((item) =>(
<li class="list" key={item.id}>
{item.name}
<br></br>
{item.body}
<br></br>
<img src={item.image}></img>
<br></br>
<button id={item.id} onClick={() => this.handleclick(item)}>delete </button>
</li>
))}
</div>
)
}
}
export default connect(null, {deleteMenuItem})(MenuItems)