最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to render a component, that contains an opened and not closed tag? React.js - Stack Overflow

programmeradmin6浏览0评论

I have an objective to make a ponent, that renders cards with nested ul tags like this: from data like this, that's being passed down with props from a parental ponent:

For that I set markers at the end of the lines where the nested ul should start, e.g. ":" when the nested ul should open and "." when the nested ul should close. But to make this code work, I need to render opened, but not closed tags.

let inUl = false;
<div className="cardBody">
        {props.body.map((el, index) => {
          if(el.endsWith(":")){
            inUl = true;
            return <li>{el}<ul>
          } else if(inUl && el.endsWith('.')){
            inUl = false;
            return <li>{el}</li></ul>
          } else {
            return <li>{el}</li>
          }
        })}
  </div>

Any help will be greately appreciated, I've a close deadline, and right now I'm literally stuck on the last part of the project - this.

I have an objective to make a ponent, that renders cards with nested ul tags like this: from data like this, that's being passed down with props from a parental ponent:

For that I set markers at the end of the lines where the nested ul should start, e.g. ":" when the nested ul should open and "." when the nested ul should close. But to make this code work, I need to render opened, but not closed tags.

let inUl = false;
<div className="cardBody">
        {props.body.map((el, index) => {
          if(el.endsWith(":")){
            inUl = true;
            return <li>{el}<ul>
          } else if(inUl && el.endsWith('.')){
            inUl = false;
            return <li>{el}</li></ul>
          } else {
            return <li>{el}</li>
          }
        })}
  </div>

Any help will be greately appreciated, I've a close deadline, and right now I'm literally stuck on the last part of the project - this.

Share Improve this question asked Oct 15, 2018 at 7:10 SthSth 5421 gold badge10 silver badges22 bronze badges 3
  • 1 Wele to Stack Overflow! Please have a look around, and read through the help center, in particular How do I ask a good question? Post code, markup, data strings, and other text as text, not as pictures of text. Why: meta.stackoverflow./q/285551/157247 – T.J. Crowder Commented Oct 15, 2018 at 7:11
  • 1. I don't see any : or . that explains your code in the data you are showing us, so it's not easy to see what would be the solution, but for what I understand @0xc14m1z's answer sounds good to me. Truth is : there are not any opened tags in React, nor in HTML. If you really think about opened tags, you are probably making a mistake in the way you think your data parsing. – arnaudambro Commented Oct 15, 2018 at 7:43
  • Probably you're right, maybe I chose the "open/close" tag option, because couldn't find a good way for initial data organisation. Right now trying that with @0xc14m1z's answered variant. Although the code is without any semicolons, a bit hard to read. – Sth Commented Oct 15, 2018 at 7:47
Add a ment  | 

2 Answers 2

Reset to default 5

But to make this code work, I need to render opened, but not closed tags.

This is a fundamental misunderstanding of how React works. You use tags in the source code to define elements, which are objects. You can't have an opening tag without a closing tag any more than you can have an opening { for an object initializer without a closing }.

Instead, you have a ponent that you pass children to, and it renders the children within its ponent. E.g.:

const UnorderedList = props => <ul>{props.children}</ul>;

...which is used like this (i.e., in a render somewhere):

return <UnorderedList><li>...</li><li>...</li></UnorderedList>;

You shouldn't think in term of open or closed tags...

To achieve your result, I would BEFORE reorganize the data in a data structure that could be easily rendered, something like this:

const elements = [
    "first ul:",
    "first li",
    "second li",
    "third li.",
    "second ul:",
    "first li",
    "second li",
    "third li.",
    "third ul:",
    "first li",
    "second li",
    "third li."
]

const makeUls = elements => {
    const uls = {}
    let currentUl
    elements.forEach(element => {
        if ( element.endsWith(":") ) {
            uls[element] = []
            currentUl = element
        } else {
            uls[currentUl].push(element)
        }
    })
    return uls
}

Calling makeUls and giving the flat array, you should have a map like this:

Object {
    "first ul:": ["first li", "second li", "third li."],
    "second ul:": ["first li", "second li", "third li."],
    "third ul:": ["first li", "second li", "third li."]
}

Once you have this kinda structure, you can easily render everything properly:

render() {
    const uls = makeUls(props.body)
    Object.keys(uls).map(ul => (
        <ul>
            { uls[ul].map(li => <li>{ li }</li> }
        </ul>
    ))
}

Consider to properly add key attribute and everything.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论