קורס React 2020 שיעור תרגול עבודה עם רשימות

זה אומר לא לשמור בכלל את הטבלה בסטייט?

האם אני צריך גם לשנות את השורה ?
const [table, setTable] = useState(data.slice(1));

אני קצת מבולבל ולא יודע מה זה אומר, תוכל לרשום לי מה לשנות בקוד שלי?

הי,

כן בדיוק. הטבלה כבר שם ב data אין צורך לשמור אותה פעם שניה. נסה לכתוב מחדש את הקומפוננטה כשהמידע היחיד שאתה שומר בסטייט הוא:

  1. לפי איזה עמודה ממיינים
  2. האם סדר המיון הוא עולה או יורד (מהגדול לקטן או מקטן לגדול)

ואת כל שאר המשתנים לחשב בכניסה לקומפוננטה

אשמח לחוות דעת על הקוד… תודה רבה!

function SortableTable(props){
const{data}=props;
const[d,setd]=useState(data);

function sort(index){
    const ArrayWithoutHeader=data.slice(1);
    const finishedArray = _.sortBy(ArrayWithoutHeader, innerArray => {
           return innerArray[index];
      });
      if(_.isEqual(finishedArray,d.slice(1))){
          _.reverse(finishedArray);
      }
       setd( _.concat(data.slice(0,1),finishedArray));
}
    return(
        <><table>
      {d.map((innerArray, index) => (
        <tr key={index}>
          {innerArray.map((item,ii )=> {
              if (index===0){
              return  <td  onClick={()=>sort(ii)}  key={item}>{item}</td>
              }
              else{
              return  <td   key={item}>{item}</td>
              }
           
            })}
        </tr>
      ))}
    </table>

            </>
    )

 }
לייק 1

הי,

לא תמיד עשיתי את זה בקורס אבל שים לב שאפשר לפרק את ה props כבר בשורת ההצהרה:

function SortableTable({data}) {

אבל יותר מעניין - אני רואה ששמרת את כל ה data בתור State פנימי. אני חושב שיהיה יותר קל (ויותר נכון) שהסטייט היחיד של הקומפוננטה יהיה לפי איזה אינדקס צריך למיין את השורות, והאם זה מיון בסדר עולה או יורד. השורות עצמן כבר נמצאות ב data, שהגיע אליך מתוך סטייט של קומפוננטה אחרת, ואין טעם לשמור את אותם נתונים בסטייט נוסף בקומפוננטה SortableTable.

(שמירה כזאת אפילו יכולה להזיק - למשל אם הקוד שיוצר SortableTable רוצה לשנות את data ולמשל להוסיף שורה, ואז SortableTable עדיין יציג את המידע הישן).

היי ינון,
מה אני מפספסת כאן המיון של הטבלה בפועל מתרחש תקין אבל בתצוגה אני לא רואה את השינוי

import React, { useState } from 'react'

export default function SortableTable({ data }) {
  const [table, setTable] = useState(data)

  function sortedTable(index) {
    const header = table[0];

    // slice delete the header table[0]
    const sortedData = table.slice(1).sort((a, b) => {
      if (a[index] < b[index]) {
        return -1;
      }
      if (a[index] > b[index]) {
        return 1;
      }
      return 0;
    });

    setTable([header, ...sortedData])
    console.log([header, ...sortedData])
  }


  return (
    <div>
      <table>
        <thead>
          <tr>
            {table[0].map((item, index) => <th style={{ cursor: 'pointer' }} key={item} onClick={(e) => sortedTable(index)} >{item}</th>)}
          </tr>
        </thead>
        <tbody>
          {table.slice(1).map((row, index) =>
            <tr key={row.id}>
              {data[index].map(item => <th key={item}>{item}</th>)}
            </tr>)}
        </tbody>
      </table>
    </div>
  )
}

בנוסף אני מקבלת בקונסול אזהרה

SortableTable.jsx:33 Warning: Each child in a list should have a unique "key" prop. Check the render method of `SortableTable`. See https://reactjs.org/link/warning-keys for more information. at tr at SortableTable (http://localhost:5173/src/components/SortableTable.jsx?t=1720435721727:19:41) at App

||SortableTable|@|SortableTable.jsx:33|
| --- | --- | --- | --- |
||Show 16 more frames|

הי הדס

שימי לב שבקוד ה JSX את משתמשת ב data כדי להציג את הנתונים, כשבעצם הנתונים אצלך שמורים במשתנה בשם table. זאת הסיבה שאת לא רואה את הנתונים הממויינים בתצוגה.

בנוסף את לא רוצה לשמור בסטייט את כל הטבלה, אלא רק את מספר העמודה לפיה ממיינים. בכניסה לפונקציה את תמיד תבצעי את המיון לפי מספר העמודה ששמור בסטייט. בצורה כזאת הקוד ימשיך לעבוד גם אם יהיה שינוי ב data שמגיע מבחוץ, והמיון ימשיך לעבוד אוטומטית על ה data החדש.

לגבי ה key יש שיעור על זה כאן:
https://www.tocode.co.il/bundles/react/lessons/key?tab=video

תודה!
שמרתי בסטייט רק את האינדקס, יצא מושלם

import React, { useState } from 'react'

export default function SortableTable({ data }) {
  const [index, setIndex] = useState(0)

  function sortedTable(idx) {
    const header = data[0];

    // slice delete the header table[0]
    const sortedData = data.slice(1).sort((a, b) => {
      if (a[index] < b[idx]) {
        return -1;
      }
      if (a[index] > b[idx]) {
        return 1;
      }
      return 0;
    });

    data = [header, ...sortedData]
    
  }


  return (
    <div>
      {sortedTable(index)}
      <table>
        <thead>
          <tr>
            {data[0].map((item, index) => <th style={{ cursor: 'pointer' }} key={index + "a"} onClick={() => setIndex(index)} >{item}</th>)}
          </tr>
        </thead>
        <tbody>
          {data.slice(1).map((row, index) =>
            <tr key={index + "b"}>
              {row.map((item, index) => <th key={index + "c"}>{item}</th>)}
            </tr>)}
        </tbody>
      </table>
    </div>
  )
}
לייק 1