React-appendChild()对现有li的React Link标记附加[object,object]

时间:2019-09-19 13:34:12

标签: javascript reactjs hyperlink append html-lists

具有一个循环,该循环限定对象的日期键/值是否与日历上的日期匹配。如果确实如此,我希望将React Link标签附加到相应的li元素。条件循环工作正常,但是由于我使用的是createTextNode(),因此当它附加Link标记时将附加[object,object]。

是否有另一种方法可以在不使用createTextNode()的情况下将Link标记附加到现有li?

我完成了通常的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 个答案:

答案 0 :(得分:1)

不知道为什么需要这样做-我很确定还有其他方法可以将基于数组的Link呈现到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

这是非常“ hacky”的-我强烈建议您寻找一种真正的“反应”方式。


编辑:

您更新的代码无效。 react-router依赖于内部上下文进行导航,*Router组件提供了该上下文-您的代码为每个链接呈现一个BrowserRouter,这意味着每个链接将具有自己的上下文。多个路由器可能无法在一页中很好地工作,因为它们会争夺对浏览器的控制权。

首先,您可能不应该在循环的每次迭代中调用ReactDOM.renderReactDOM.render控制着cell内部的所有内容-一次又一次地呈现它,意味着只有最后一次调用才有效。

第二,您的BrowserRouter应该放在应用的顶层(例如,在您的根组件中)。

再次,像这样操纵dom并不是您应该使用React的方式。我很好奇您正在构建哪种类型的应用程序,以及它的结构形式?


这就是我认为您应该做的-因为您已经在使用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。

答案 1 :(得分:0)

如果我正确地回答了您的问题,则您试图在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....)
        }
    }