React.js中对嵌套组件中的列表进行排序

huangapple go评论125阅读模式
英文:

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 &#39;./logo.svg&#39;;
import &#39;./App.css&#39;;
import { useState, useRef } from &#39;react&#39;;
import classes from &#39;./ChoreList.module.css&#39;;
// 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: &quot;Cucumber&quot;,
done: true
}
];
function ChoreList(props) {
const { items, handleDelete, handleCheck, ...my_props } = props;
// function clickEvent(my_event) {
//   my_event.preventDefault();
//   handleDelete(my_event, );
// }
return (
&lt;ul className=&#39;myList&#39;&gt;
{items.map(element =&gt; &lt;li id={element.id} key={element.id}&gt;
&lt;input type=&#39;checkbox&#39; 
checked={element.done} 
onChange={evt =&gt; handleCheck(evt, 
element.id)}&gt;
&lt;/input&gt; 
&lt;span className={element.done ? classes.done : classes.notdone }&gt;{element.item}&lt;/span&gt; 
(&lt;a href=&#39;null&#39; onClick={(evt) =&gt; handleDelete(evt, element.id)}&gt;Remove&lt;/a&gt;)&lt;/li&gt;)}
&lt;/ul&gt;
)
} 
function Summary(props) {
// const { items } = props;
// items.length  would then refer to the number of item
return (
&lt;div className=&#39;b-bottom&#39;&gt;{props.items.length} items&lt;/div&gt;
)
}
function AddElement(props) {
const { addItem, addRef } = props;
return (
&lt;div className=&#39;holder&#39;&gt;
&lt;label htmlFor=&#39;newitem&#39; className=&#39;label-input&#39;&gt;Add Item&lt;/label&gt; 
&lt;input ref={addRef} type=&#39;text&#39; id=&#39;newitem&#39; className=&#39;form-control&#39; /&gt;
&lt;button onClick={addItem} className=&#39;button-t&#39;&gt;Add&lt;/button&gt;
&lt;/div&gt;
)
}
function sortByItem(props) {
}
function AddSort(props) {
const [ item, setitem ] = useState(elements);
const sortItem = (selectEvent) =&gt; {
const options = {
&quot;a-z&quot;: [...item].sort((a, b) =&gt; a.item &gt; b.item),
&quot;z-a&quot;: [...item].sort((a, b) =&gt; (a &lt; b ? 1 : -1))
};
setitem(options[selectEvent.target.value]);
};
return (
&lt;div className=&quot;dropmenu&quot;&gt;
&lt;select onChange={sortItem}&gt;
&lt;option value=&quot;a-z&quot;&gt;Alphabetical&lt;/option&gt;
&lt;option value=&quot;z-a&quot;&gt;Order Added&lt;/option&gt;
&lt;/select&gt;
&lt;/div&gt;
);
}
function App() {
const [ item, setitem ] = useState(elements);
const newChoreRef = useRef();
function handleDelete(user_event, id) {
user_event.preventDefault();
const new_item = item.filter(e =&gt; e.id !== id);
setitem(new_item);
}
function handleCheck(user_event, id) {
console.log(&quot;need to change the status of &quot; + 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 =&gt; (e.id === id) ? 
{
id: e.id, 
item: e.item, 
done: user_event.target.checked
} 
: e);
// somewhat simpler version
// const new_item = item.map(e =&gt; {
//   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 =&gt; {
//   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 (
&lt;&gt;
&lt;div className=&#39;shoplist-holder&#39;&gt;
&lt;div className=&#39;header-holder&#39;&gt;
&lt;div className=&#39;header-col&#39;&gt;
&lt;div className=&#39;header&#39;&gt;&lt;h1&gt;Sams Shopping List&lt;/h1&gt;&lt;/div&gt;
&lt;Summary items={item}&gt;&lt;/Summary&gt;
&lt;/div&gt;
&lt;div className=&#39;sub-header&#39;&gt;&lt;AddSort items={item}&gt;&lt;/AddSort&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;AddElement addItem={addItem} addRef={newChoreRef}&gt;&lt;/AddElement&gt;
&lt;ChoreList items={item} handleDelete={handleDelete} handleCheck={handleCheck}&gt;&lt;/ChoreList&gt;
&lt;/div&gt;
&lt;/&gt;
);
}
export default App;

答案1

得分: 0

“待办事项列表”是在App组件内部维护的状态,但您正在尝试在AddSort组件内部对列表进行排序。

您需要将sortItem()方法移到App组件,并将该方法作为一个prop传递 - 就像您在handleDeletehandleCheck处理程序中所做的一样。

<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.

&lt;AddSort sortItem={sortItem} items={item}&gt;&lt;/AddSort&gt;

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: &quot;Cucumber&quot;
},
{
id: 2, 
item: &quot;Carrots&quot;
},
{
id: 3,
item: &quot;Zucchinis&quot;
}
];
console.log(elements.sort((a,b) =&gt; a.item &gt; b.item ? 1 : -1))
(3) [{...}, {...}, {...}]
0:(3) {id: 2, item: &quot;Carrots&quot;}
1:(3) {id: 1, item: &quot;Cucumber&quot;}
2:(3) {id: 3, item: &quot;Zucchinis&quot;}

huangapple
  • 本文由 发表于 2023年3月7日 05:03:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/75655826.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定