Как запустить компонент в цикле и закрыть все 3 итерации - PullRequest
0 голосов
/ 25 июня 2019

Здравствуйте, я ищу решение для открытия тега в цикле и закрыть его все 3 итерации. Цель состоит в том, чтобы создать гриль, основанный на ряду контейнера и col. Моя проблема в том, что я не знаю, как это сделать.

Пример:

    render(){
        const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]
        let arrayEl = [];
        let count = 1; 
          for ( let i = 0; i < arrayName.length; i++ ) {
             let name = arrayName[i]

             if (count === 1) {
                 arrayEl.push(<div className="row">);
                 arrayEl.push(<p className="col">{name}</p>);
                 count ++;
                 continue;
             }
             if (count === 3) {
                 arrayEl.push(<p className="col" >{name}</p>);
                 arrayEl.push(</div>);
                 count = 1;
                 continue;
             }
           }
        return (<div className="container">{arrayEl}</div>)
    }

и желаемый результат:

<div className="container">
    <div className="row">
        <div className="col">john</div>
        <div className="col">bob</div>
        <div className="col">joe</div>
    </div>
    <div className="row">
        <div className="col">mat</div>
        <div className="col">toto</div>
        <div className="col">tata</div>
    </div>
</div>

спасибо за помощь

EDIT

Проблема в том, что мы не можем добавить элемент или компонент, не закрыв его.

Плохо:

arrayEl.push(<div className="row">)

хорошо:

arrayEl.push(<div className="row"/>) or arrayEl.push(<div className="row"></div>)

Ответы [ 4 ]

1 голос
/ 25 июня 2019

Нельзя раздвигать HTML-элементы по частям, например,

arrayEl.push(<div>)

arrayEl.push(</div>)

Вы должны перемещать элементы от начала до конца, например,

arrayEl.push(<div>{children}</div>)

Для этого вам необходимо мгновенно вывести все cols в row, как в примере кода ниже.

render() {
    const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"];
    let rows = [];
    let currentCols = [];

    for (let i = 0; i < arrayName.length; i++) {
        let name = arrayName[i];
        currentCols.push(<div className="col" key={i}>{name}</div>);

        if ((i+1) % 3 === 0) {
          rows.push(<div className="row" key={i}>{currentCols}</div>);
          currentCols = [];                
        }
    }

    rows.push(currentCols);
    return (<div className="container">{rows}</div>)
}

JSFiddle demo

Вместо использования переменной count я просто использовал переменную i из вашего цикла и проверил, делится ли (i + 1) на 3: % 3 === 0. Если это так, это означает, что у вас уже есть 3 столбца в строке; Мы можем поместить currentCols в массив rows и очистить его.

1 голос
/ 25 июня 2019

Я бы изменил ваши данные с:

 ["john", "bob", "joe", "mat", "toto", "tata"]
// to
 [["john", "bob", "joe"], ["mat", "toto", "tata"]]

Оформить заказ https://lodash.com/docs/4.17.11#chunk например, это

И тогда вы можете вложить 2 .map для репликации структуры в JSX:


const chunk = (arr, chunckSize) => arr.reduce((chunks, value, index) => {
  const chunckIndex = Math.floor(index / chunckSize)
  const c = chunks[chunckIndex] || (chunks[chunckIndex] = [])
  c.push(value)
  return chunks
}, [])

render() {
    const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]

    return (
        <div className="container">
            {chunk(arrayName, 3).map(names => (
                <div className="row">
                    {names.map(name => <div className="col">{name}</div>)}
                </div>
            ))}
        </div>
    )
}
0 голосов
/ 25 июня 2019

Проблема вашего подхода в том, что JSX не является html, поэтому </div> выражение недопустимо.

Императивный подход ради полноты. :)

Кстати, вам нужны ключи.

render(){
    const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"]
      let arrayEl = [];
      let row = [];
      const batchSize = 3
      for ( let i = 0, i < arrayName.length, i++ ) {
         const name = arrayName[i]
         row.push(<div className="col" key={name}>{name}</div>)

         // we have a full batch or the last element 
         if (row.length === batchSize || i === arrayName.length - 1) { 
           arrayEl.push(<div className="row" key={i/batchSize}>{row}</div>)
           row = []
         }
       }
    return (<div className="container">{arrayEl}</div>)
}
0 голосов
/ 25 июня 2019

Хорошо, так что вы должны изменить логику в вашем цикле, чтобы получить желаемый результат.Вот что я сделал в качестве примера с JavaScript.Вам просто нужно адаптировать его с вашим компонентом.

const arrayName = ["john", "bob", "joe", "mat", "toto", "tata"];
let arrayEl = [];

for (let i = 0; i < arrayName.length; i++) {
  let name = arrayName[i];
  if ((i % 3) == 0) {
    arrayEl.push(`<div className = "row">\n`);
  }
  arrayEl.push(`<p className = "col">${name}</p>\n`);
  if (((i + 1) % 3) == 0) {
    arrayEl.push(`</div>\n`);
  }
}
console.log(`<div className="container">\n ${arrayEl.join(' ')}</div>`);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...