具有一个循环,该循环限定对象的日期键/值是否与日历上的日期匹配。如果确实如此,我希望将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);
}
}
答案 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.render
。 ReactDOM.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....)
}
}