React - appendChild () тег React Link к существующему li appends [объект, объект] - PullRequest
0 голосов
/ 19 сентября 2019

Иметь цикл, который определяет, соответствует ли ключ / значение даты объекта дате в календаре.Если это так, я хочу добавить тег React Link к соответствующему элементу li.Цикл условия работает нормально, но когда он добавляет тег Link, он добавляет [объект, объект], поскольку я использую createTextNode ().

Есть ли другой способ добавить тег Link к существующему li без использованияcreateTextNode ()?

Я сделал обычный поиск в Google без удачи.

for (let i = 0; i < events.length; i++) {
     const link = (<Link to={`/events/${events[i].eventId}`}> . 
                  {events[i].title}</Link>);
     const eventLink = document.createTextNode(link);

     if (events[i].date.slice(15) === day.toString()) {
     cell.appendChild(eventLink);
    }
}

Нужен элемент li, содержащий тег React Link, а не текстовый узел.

ОБНОВЛЕНИЕ Код с рендерингом ReactDOM и BrowserRouter, но когда я щелкаю тег Link, React не рендерит компонент маршрута.

for (let i = 0; i < events.length; i++) {
    const link = (
                <>
        {day.toString()}
        <Link to={`/events/${events[i].eventId}`}>{events[i].title}</Link>
        </>);

        const eventDate = events[i].date.split('-');
        const eventYear = eventDate[0];
        const eventMonth = eventDate[1];
        const eventDay = eventDate[2];
        if (eventDay === day.toString() &&
        eventMonth === (month + 1).toString() &&
        eventYear === year.toString()) {
        ReactDOM.render(<BrowserRouter>{link}</BrowserRouter>, cell);
            }
        }

Ответы [ 2 ]

1 голос
/ 19 сентября 2019

Не уверен, почему вам нужно сделать это таким образом - я уверен, что есть и другие способы рендеринга Link s на основе массива в вашу DOM.

Однако, если вы настаиваете, вы должны использовать ReactDOM

В вашем цикле:

// create an empty div to hold our links:
const tempDiv = document.createElement('div');

// render links into the empty div
ReactDOM.render(eventLinks, tempDiv);

// append the link, since you don't want the div in cell
cell.appendChild(tempDiv.firstChild); // there is only 1 child

Это очень "хаки" - я очень рекомендую поискатьнастоящий "Реактивный" способ сделать это.


РЕДАКТИРОВАТЬ:

ваш обновленный код не будет работать.react-router полагается на внутренний контекст для навигации, и компоненты *Router предоставляют этот контекст - ваш код отображает BrowserRouter для каждой ссылки, означая, что каждая ссылка будет иметь свой собственный контекст.Несколько маршрутизаторов, вероятно, не будут хорошо работать на одной странице, поскольку они будут бороться с контролем над браузером.

Прежде всего вам, вероятно, не следует вызывать ReactDOM.render в каждой итерации цикла.ReactDOM.render получает контроль над всем содержимым вашего cell - рендеринг его снова и снова означает, что работает только последний вызов.

Во-вторых, ваш BrowserRouter должен быть размещен на верхнем уровне вашего приложения (например, в вашем корневом компоненте).

Опять же, манипулирование dom таким способом не является тем, как вы должны использовать React.Мне интересно, какое приложение вы создаете и как оно структурировано?


Итак, вот что, я думаю, вам следует сделать - поскольку вы уже используете реагирование, я думаю, что существует дерево компонентов (например, у вас есть компонент верхнего уровня, который отображает другие компоненты и т. Д.)

Итак, в самом верху вашего приложения вы должны обернуть все в BrowserRouter.

// index.js, maybe.

// assuming App is your "top level component"
import App from './App.jsx';

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
, document.getElementById('root'))

И теперь создайте EventLinks компонент, который отображает все ссылки:

// EventLinks.jsx

const EventLinks = ({ events }) => (
  events.map((event) => (
    <li key={event.eventId}>
      <Link to={`/events/${event.eventId}`}>
        {event.title}
      </Link>
    </li>
  ))
);

В вашем компоненте, где живет cell, визуализируйте ссылки напрямую.

// Cell component

const Cell = ({ events }) => {
  // filter events if you need to here, since you have that `if` logic originally

  const visibleEvents = events.filter(filterFunction);

  return (
    <ul>
      <EventLinks events={visibleEvents} />
    </ul>
  );
}

Возможно, это не совсем соответствует структуре вашего приложения, но я надеюсь, что вы поняли.

, поэтому ваш App отображает макет и Cell компонент, а затем ваш Cell рендеринг EventLinks.

Честно говоря, вы вообще не должны использовать ReactDOM, за исключением единственной точки входа в ваше приложение.

0 голосов
/ 19 сентября 2019

если я правильно получаю ваши вопросы, вы пытаетесь добавить к элементу li ссылку (ссылки React) в виде текста внутри элемента li (и, если я верен в качестве интерактивной ссылки ..... элемента тега привязки)

ячейка должна быть правильным элементом li, в котором я предполагаю, что вы выполняете итерацию параллельно событию, тогда вот возможное решение:

for (let i = 0; i < events.length; i++) {
     const link = (<Link to={`/events/${events[i].eventId}`}> . 
                  {events[i].title}</Link>);

     if (events[i].date.slice(15) === day.toString()) {
     let tempComponent = ReactDOM.createElement("li",{...propertiesIfNeeded},link)
     ReactDOM.render(tempComponent,cell) //you could also pass here refrece to cell/li items where i wrote cell(eg.document.querySelect....)
    }
}

или решение 2, создающее li как частьКомпонент ссылки, который вы создаете в итерации:

for (let i = 0; i < events.length; i++) {
         const link = (<li><Link to={`/events/${events[i].eventId}`}> . 
                      {events[i].title}</Link></li>);

         if (events[i].date.slice(15) === day.toString()) {
         ReactDOM.render(link,cell) //you could also pass here refrece to cell/li items where i wrote cell(eg.document.querySelect....)
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...