英文:
React.js sorting a list in nested components
问题
以下是您要翻译的内容:
"How can I sort my shopping list? I have the code as addSort function. Everything looks good to me not sure what im doing wwrong. I can't get it to work. I would like when the user selects the dropdown they can select the option of Alphabetical or list added order. I have the ddropdown working. The function looks right but I can't get it to work."
import logo from './logo.svg';
import './App.css';
import { useState, useRef } from 'react';
import classes from './ChoreList.module.css';
const elements = [
{
id: 1,
item: "Cucumber",
done: true
}
];
function ChoreList(props) {
const { items, handleDelete, handleCheck, ...my_props } = props;
return (
<ul className='myList'>
{items.map(element => <li id={element.id} key={element.id}>
<input type='checkbox'
checked={element.done}
onChange={evt => handleCheck(evt,
element.id)}>
</input>
<span className={element.done ? classes.done : classes.notdone }>{element.item}</span>
(<a href='null' onClick={(evt) => handleDelete(evt, element.id)}>Remove</a>)
</li>)}
</ul>
)
}
function Summary(props) {
return (
<div className='b-bottom'>{props.items.length} items</div>
)
}
function AddElement(props) {
const { addItem, addRef } = props;
return (
<div className='holder'>
<label htmlFor='newitem' className='label-input'>Add Item</label>
<input ref={addRef} type='text' id='newitem' className='form-control' />
<button onClick={addItem} className='button-t'>Add</button>
</div>
)
}
function AddSort(props) {
const [ item, setitem ] = useState(elements);
const sortItem = (selectEvent) => {
const options = {
"a-z": [...item].sort((a, b) => a.item > b.item),
"z-a": [...item].sort((a, b) => (a < b ? 1 : -1))
};
setitem(options[selectEvent.target.value]);
};
return (
<div className="dropmenu">
<select onChange={sortItem}>
<option value="a-z">Alphabetical</option>
<option value="z-a">Order Added</option>
</select>
</div>
);
}
function App() {
const [ item, setitem ] = useState(elements);
const newChoreRef = useRef();
function handleDelete(user_event, id) {
user_event.preventDefault();
const new_item = item.filter(e => e.id !== id);
setitem(new_item);
}
function handleCheck(user_event, id) {
console.log("need to change the status of " + id);
const new_item = item.map(e => (e.id === id) ?
{
id: e.id,
item: e.item,
done: user_event.target.checked
}
: e);
setitem(new_item);
}
function addItem(evt) {
const choreDescription = newChoreRef.current.value;
const newchore = {
id: item.length + 1,
item: choreDescription,
done: false
}
const new_item = item.concat([newchore]);
setitem(new_item);
}
return (
<>
<div className='shoplist-holder'>
<div className='header-holder'>
<div className='header-col'>
<div className='header'><h1>Sams Shopping List</h1></div>
<Summary items={item}></Summary>
</div>
<div className='sub-header'><AddSort items={item}></AddSort></div>
</div>
<AddElement addItem={addItem} addRef={newChoreRef}></AddElement>
<ChoreList items={item} handleDelete={handleDelete} handleCheck={handleCheck}></ChoreList>
</div>
</>
);
}
export default App;
英文:
How can I sort my shopping list? I have the code as addSort function. Everything looks good to me not sure what im doing wwrong. I can't get it to work. I would like when the user selects the dropdown they can select the option of Alphabetical or list added order. I have the ddropdown working. The function looks right but I can't get it to work.
import logo from './logo.svg';
import './App.css';
import { useState, useRef } from 'react';
import classes from './ChoreList.module.css';
// maintain state by importing the usestate
//Possible user actions to events:
//Delete an element
//Mark or unmark as done
// add an element (chore)
//list of elementswith array of items with unique ids
//three attribute for each one of the objects
// Possible user actions to events:
// delete an element
// mark or unmark as done (possibly with a checkbox)
// add an element (chore)
//
const elements = [
{
id: 1,
item: "Cucumber",
done: true
}
];
function ChoreList(props) {
const { items, handleDelete, handleCheck, ...my_props } = props;
// function clickEvent(my_event) {
// my_event.preventDefault();
// handleDelete(my_event, );
// }
return (
<ul className='myList'>
{items.map(element => <li id={element.id} key={element.id}>
<input type='checkbox'
checked={element.done}
onChange={evt => handleCheck(evt,
element.id)}>
</input>
<span className={element.done ? classes.done : classes.notdone }>{element.item}</span>
(<a href='null' onClick={(evt) => handleDelete(evt, element.id)}>Remove</a>)</li>)}
</ul>
)
}
function Summary(props) {
// const { items } = props;
// items.length would then refer to the number of item
return (
<div className='b-bottom'>{props.items.length} items</div>
)
}
function AddElement(props) {
const { addItem, addRef } = props;
return (
<div className='holder'>
<label htmlFor='newitem' className='label-input'>Add Item</label>
<input ref={addRef} type='text' id='newitem' className='form-control' />
<button onClick={addItem} className='button-t'>Add</button>
</div>
)
}
function sortByItem(props) {
}
function AddSort(props) {
const [ item, setitem ] = useState(elements);
const sortItem = (selectEvent) => {
const options = {
"a-z": [...item].sort((a, b) => a.item > b.item),
"z-a": [...item].sort((a, b) => (a < b ? 1 : -1))
};
setitem(options[selectEvent.target.value]);
};
return (
<div className="dropmenu">
<select onChange={sortItem}>
<option value="a-z">Alphabetical</option>
<option value="z-a">Order Added</option>
</select>
</div>
);
}
function App() {
const [ item, setitem ] = useState(elements);
const newChoreRef = useRef();
function handleDelete(user_event, id) {
user_event.preventDefault();
const new_item = item.filter(e => e.id !== id);
setitem(new_item);
}
function handleCheck(user_event, id) {
console.log("need to change the status of " + id);
// update state so that done is set to checked (or not)
console.log(user_event.target.checked);
// version that uses the ternary operator
const new_item = item.map(e => (e.id === id) ?
{
id: e.id,
item: e.item,
done: user_event.target.checked
}
: e);
// somewhat simpler version
// const new_item = item.map(e => {
// if (e.id == id) {
// return {
// id: e.id,
// item: e.item,
// done: user_event.target.checked
// }
// }
// else {
// return e;
// }
// });
// original version
// const new_item = item.map(e => {
// if (e.id == id) {
// return {
// id: e.id,
// item: e.item,
// done: user_event.target.checked
// }
// }
// else {
// return {
// id: e.id,
// item: e.item,
// done: e.done
// }
// }
// });
setitem(new_item);
}
function addItem(evt) {
const choreDescription = newChoreRef.current.value;
const newchore = {
id: item.length + 1, // it would be better to keep a state that incremented the id
item: choreDescription,
done: false
}
const new_item = item.concat([newchore]);
setitem(new_item);
}
return (
<>
<div className='shoplist-holder'>
<div className='header-holder'>
<div className='header-col'>
<div className='header'><h1>Sams Shopping List</h1></div>
<Summary items={item}></Summary>
</div>
<div className='sub-header'><AddSort items={item}></AddSort></div>
</div>
<AddElement addItem={addItem} addRef={newChoreRef}></AddElement>
<ChoreList items={item} handleDelete={handleDelete} handleCheck={handleCheck}></ChoreList>
</div>
</>
);
}
export default App;
答案1
得分: 0
“待办事项列表”是在App
组件内部维护的状态,但您正在尝试在AddSort
组件内部对列表进行排序。
您需要将sortItem()
方法移到App
组件,并将该方法作为一个prop传递 - 就像您在handleDelete
和handleCheck
处理程序中所做的一样。
<AddSort sortItem={sortItem} items={item}></AddSort>
您还可以在useEffect()
中调用sortItem()
,以提供初始排序。
英文:
The list of chores is maintained in state inside the App
component, yet you are attempting to sort the list within the AddSort
component.
You need to move the sortItem()
method to the App
component and pass the method as a prop - just like you do with the handleDelete
and handleCheck
handlers.
<AddSort sortItem={sortItem} items={item}></AddSort>
You may also find it useful to call sortItem()
in useEffect()
to provide an initial sort too.
答案2
得分: -1
I don't know what is your problem, but it's not about sorting.
请提供一个简单的示例,当您遇到问题时(这也可能帮助您意识到问题并非您所认为的那样)
In any case, this would work fine:
无论如何,这应该正常运行:
const elements = [
{
id: 1,
item: "Cucumber"
},
{
id: 2,
item: "Carrots"
},
{
id: 3,
item: "Zucchinis"
}
];
console.log(elements.sort((a, b) => a.item > b.item ? 1 : -1))
(3) [{...}, {...}, {...}]
0: (3) {id: 2, item: "Carrots"}
1: (3) {id: 1, item: "Cucumber"}
2: (3) {id: 3, item: "Zucchinis"}
英文:
I don't know what is your problem, but it's not about sorting.
Please provide a simple sample when you have issues (it might also help you to realize the issue is not what you think it is)
In any case, this would work fine :
const elements = [
{
id: 1,
item: "Cucumber"
},
{
id: 2,
item: "Carrots"
},
{
id: 3,
item: "Zucchinis"
}
];
console.log(elements.sort((a,b) => a.item > b.item ? 1 : -1))
(3) [{...}, {...}, {...}]
0:(3) {id: 2, item: "Carrots"}
1:(3) {id: 1, item: "Cucumber"}
2:(3) {id: 3, item: "Zucchinis"}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论