score:1

Accepted answer

there is nothing you need to change in your code as is (besides the extraneous semicolon in the ternary expression). simply pass the string "h1" as the value of the component prop.

jsx is just syntactic sugar for calling react.createelement. if the jsx tag starts with an upper case letter it is left as is and is passed as the first argument to react.createelement, otherwise if the tag name begins with a lower case letter it will be turned into a string and then passed as the first argument.

function testcomponent(){
  return <div>testing!</div>;
}

the above gets turned into this plain javascript:

function testcomponent(){
  return react.createelement("div", null, "testing!");
}

when the example testcomponent above is rendered, react.createelement will create a react element that renders to a ’normal' <div> element.

for your component, wherever the <wrapper> jsx tag is used, wrapper will be passed as the first argument to react.createelement. the value of wrapper could be a react component, but it could also just be a string, such as "div". so all you’ve have to do is use your code like this:

const textlikerender = ({ value, component: wrapper }) => {
  if (value.type === "html") {
    return <wrapper dangerouslysetinnerhtml={{__html: value.content}} />;
  } else {
    return <wrapper>{value}</wrapper>;
  }
}

<textlikerender value={{type: 'html', content: 'this is <br/> html'}} component="h1" />

finally — this is irrelevant to the question, but a component like this would probably be better with type and value both being separate props, and even better would be to not have textlikerender take a component prop, and leave wrapping it to the code using it. and, given you can pass any value as a prop, it would be much better (not to mention safer and more secure) to avoid dangerouslysetinnerhtml completely and pass ["this is ", <br />, " html"] as the value instead, if that’s possible.

score:2

one possible solution is to use react.createelement inside textlikerender. this way you can pass component as string.

export const textlikerender = ({ value, component:wrapper })=> {
  return value && value.type==='html' ?
    react.createelement (wrapper, { dangerouslysetinnerhtml: {__html: value.content} }) :
    react.createelement (wrapper, {}, value && value.content)
}

usage

<textlikerender value={{type:'html',content:'this is <br/> html'}} component='h1' />

demo is here


Related Query

More Query from same tag