Жагсаалт ба түлхүүрүүд

Эхлээд Жаваскриптэд хэрхэн жагсаалтыг хувиргадаг талаар эргэн саная.

Доорх өгөгдсөн кодод бид map() функц ашиглах тоон жагсаалтын утгыг хоёр дахин нэмэгдүүлж байна. Бид шинэ жагсаалтад map() функцээс буцсан хоёр дахин нэмэгдүүлсэн оноон мөн лог бичилт хийлээ:

const numbers = [1, 2, 3, 4, 5];
const doubled = numbers.map((number) => number * 2);
console.log(doubled);

Энэ код [2, 4, 6, 8, 10] утгын консоль руу лог хийлээ.

React дээр жагсаалтыг элементүүд-ийн жагсаалт болгон хөрвүүлэх нь их төстэй байдаг.

Олон компонентүүдийг дүрслэх

You can build collections of elements and include them in JSX using curly braces {}.

Та {} угалзан хаалт ашиглан элементүүдийн

Доор бид Жаваскриптийн map() функц ашиглан тоон жагсаалтаар давтан элэмент бүр дээр <li> буцаасан. Эцэст нь listItems-д утгуудаа оноосон байна:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li>{number}</li>
);

Бид listItems-аа <ul> элэмент дотор багтаан DOM руу дүрсэлсэн:

ReactDOM.render(
  <ul>{listItems}</ul>,
  document.getElementById('root')
);

Try it on CodePen

Энэ код 1-ээс 5 хүртэлх тоон утгыг суман жагсаалтаар(bullet list) дүрсэлдэг.

Энгийн жагсаалт компонент

Usually you would render lists inside a component. Ихэвсчлэн та жагсаалтыг компонент дотор дүрсэлдэг.

Бид өмнөх жишээг тоонуудын жагсаалт хүлээн авж, элэментүүдийн жагсаалт болгон гаргадаг компонент болгон сайжруулж чадна.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li>{number}</li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Чи энэ кодыг ажиллуулах үед түлхүүр жагсаалтын хэсэгт олгохийг зөвлөсөн анхааруулга харна. “Түлхүүр” бол тусгай тэмдэгт төрөлтэй шинж чанар бөгөөд чи үүнийг элэментүүдийн жагсаалт үүсгэж үедээ ашиглах хэрэгтэй. Энэ нь яагаад чухал болох талаар дараагийн хэсэгт ярилцах болно.

Түлхүүрnumbers.map() дотор оноогоод түлхүүр байхгүй байгаа анхааруулгыг засцгаая.

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <li key={number.toString()}>
      {number}
    </li>
  );
  return (
    <ul>{listItems}</ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Try it on CodePen

Түлхүүрүүд

Түлхүүрүүд нь React-д ямар хэсэг өөрчлөгдсөн, нэмэгдсэн эсвэл устгагдсан талаар танихад тусалдаг. Түлхүүрүүд жагсаалтын дотор байгаа элэментүүдэд өгөгдөх нь найдвартай таних тэмдэг болдог:

const numbers = [1, 2, 3, 4, 5];
const listItems = numbers.map((number) =>
  <li key={number.toString()}>
    {number}
  </li>
);

Тэмдэгт төрөл ашиглан бусад утгуудаас ялгах нь түлхүүр сонгох сайн арга юм. Ихэвчлэн та өөрийн өгөгдлөөг ID-г түлхүүр болгон ашиглана:

const todoItems = todos.map((todo) =>
  <li key={todo.id}>
    {todo.text}
  </li>
);

Танд утгаа хангалттай тодорхойлж чадах түлхүүр дүрслэгдсэн утгууд дотор чинь байхгүй бол та жагсаалтын индексийг ашиглах нь сүүлийн сонголт байж болох юм:

const todoItems = todos.map((todo, index) =>
  // Only do this if items have no stable IDs
  <li key={index}>
    {todo.text}
  </li>
);

Хэрэв жагсаалтын эрэмбэ өөрчлөгдөх бол бид индексийг түлхүүр болгон ашиглахийг зөвлөдөггүй. Энэ нь ажиллагааны хурд сөргөөр нөлөөлөх болон компонентийн төлөвт асуудал үүсгэж болзошгүй. Индексийг түлхүүр болгон ашиглахийн сөрөг нөлөөг илүү тайлбарласан Robin Pokorny-н нийтлэлийг уншиж болно. Хэрэв та жагсаалтын утгууддаа тусгайлан түлхүүр зааж өгөхгүй бол React индексийг анхны төлөв(default)-р түлхүүр болгон ашиглана.

Хэрэв та илүү нарын сонирхвол түлхүүр яагаад чухал талаар илүү гүнзгий тайлбар нийтлэлийг уншина уу.

Extracting Components with Keys

Түлхүүрүүд нь жагсаалтын үед л илүү ойлгомжтой.

Жишээлбэл, Хэрэв та ListItem компонент гаргаж авах бол түлхүүрийг ListItem /> элэмэнтүүд дээр хэрэглэх нь ListItem<li> элементэд хэрэглэх нь илүү тохиромжтой.

Жишээ: Түлхүүрийн буруу ашиглалт

function ListItem(props) {
  const value = props.value;
  return (
    // Буруу! Энд түлхүүр тодорхойлох шаардлагагүй:
    <li key={value.toString()}>
      {value}
    </li>
  );
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Буруу! Түлхүүр энд тодорхойлох ёстой:
    <ListItem value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Жишээ: Түлхүүрийн зөв ашиглалт

function ListItem(props) {
  // Correct! There is no need to specify the key here:
  return <li>{props.value}</li>;
}

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    // Correct! Key should be specified inside the array.
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
  <NumberList numbers={numbers} />,
  document.getElementById('root')
);

Try it on CodePen

A good rule of thumb is that elements inside the map() call need keys. map() дуудалт доторх элэментүүдэд түлхүүр хэрэглэх нь хэрэгжүүлж болох зөвлөмж юм.

Түлхүүрүүд зөвхөн харалдаа утгууддаа л дахин давтагдашгүй байх ёстой

Жагсаалтад ашиглагдаж байгаа түлхүүрүүд нь жагсаалт доторх утгуудаасаа л ялгагдахад болно. Тэдгээр нь нэгдсэн хүрээнд дахин давтагдашгүй байх албагүй бөгөөд бид хоёр өөр жагсаалтад адилхан түлхүүрүүд ашиглаж болно:

function Blog(props) {
  const sidebar = (
    <ul>
      {props.posts.map((post) =>
        <li key={post.id}>
          {post.title}
        </li>
      )}
    </ul>
  );
  const content = props.posts.map((post) =>
    <div key={post.id}>
      <h3>{post.title}</h3>
      <p>{post.content}</p>
    </div>
  );
  return (
    <div>
      {sidebar}
      <hr />
      {content}
    </div>
  );
}

const posts = [
  {id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
  {id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
  <Blog posts={posts} />,
  document.getElementById('root')
);

Try it on CodePen

Түлхүүрүүд нь React-д туслах үүрэг гүйцэтгэдэг бөгөөд таний компонент руу илгээгдэхгүй. Хэрэв танд түлхүүртэй ижил компонент дотор чинь хэрэгтэй бол өөр нэрээр шинж чанар(prop) тусгайлан илгээх хэрэгтэй:

const content = posts.map((post) =>
  <Post
    key={post.id}
    id={post.id}
    title={post.title} />
);

Дээрх жишээнд Post компонент нь props.id-г уншиж чадах боловч props.key-г уншиж чадахгүй.

Embedding map() in JSX

Өмнөх жишээнүүдэд listItems хувьсагчийг тусад нь зарлаж JSX дотор ашигласан:

function NumberList(props) {
  const numbers = props.numbers;
  const listItems = numbers.map((number) =>
    <ListItem key={number.toString()}
              value={number} />
  );
  return (
    <ul>
      {listItems}
    </ul>
  );
}

JSX угалзан хаалт ашиглан ямарч илэрхийлэл залгах-ийг зөвшөөрдөг учир map()-г үр дүн дотор нь ашиглаж болно:

function NumberList(props) {
  const numbers = props.numbers;
  return (
    <ul>
      {numbers.map((number) =>
        <ListItem key={number.toString()}
                  value={number} />
      )}
    </ul>
  );
}

Try it on CodePen

Заримдаа энэ нь илүү цэвэрхэн код бичих боломжийг олгодог ч энэ хэвшил нь ойлгомжгүй болгож болзошгүй. Жаваскрипттэй адилаар кодыг уншихад амархан байлгах үүднээс хувьсагчийг гаргаж авах нь таний шийдвэр юм. Гэхдээ map()-н доторх код чинь хэтэрхий олон дамжсан(nested) бол компонент гаргаж авах нь илүү дээр байж магадгүй.