首页 > 解决方案 > 使用动态变量从字符串中反应渲染 html

问题描述

我正在使用打字稿中的反应应用程序。从 API,我有这个输入:

a) 变量名列表["name", "surname"]

b)带有变量的简单html形式的几个字符串"<p>Hello, how are you {name}?</p>"

c) 带有变量的输入数量,例如{input1: "name"}

一切都是字符串/JSON

我需要做的是:呈现从 API 接收的简单 html(只有几个标签),但在这些动态输入和字符串中的变量之间“创建”绑定

在静态世界中,结果如下所示:

[name, setName] = useState("")
<p>Hello, how are you {name}?</p>
<input type="text" onChange={e => setName(e.target.value)}/>

然而,这一切都是动态的。字符串"<p>Hello, how are you {name}?</p>"不会自行绑定到输入。

我试过了:

设置变量[vars, setVars] = useState({}),每个动态变量的属性,与

a) dangerouslySetInnerHTML - 仅呈现 html(不能将内部变量绑定到输入)

b) react-html-parser - 同上

c)babel.transform - 无法使其工作,因为这是动态完成的,并且在浏览器中,它找不到正确的预设,我无法使 mimified babel.js 与 typescript 一起工作如何在 React 中使用 JSX 呈现字符串

你看到一些简单的方法吗?例如,我如何使用 React.createElement 来呈现带有“live”变量的 html,表示为 {variableName}?或者可能是开箱即用的东西?给每个元素一个类并在 DOM 中找到该类并使用输入更改编辑文本可能非常不理想?

我希望这可能是一个更好的例子:

{response:
   {
       variables: ["name", "name2", "mood"],
       texts: [
           "<em> Hello! My name is {name}</em>",
           "<p> Hi {name} ! I am <strong>{name2}</strong> and I feel {mood} today</p>"      
       ],
       inputs: [
          {
                label: "How do i feel?"
                input: {mood}
          }
       ]
   }
} 

标签: javascripthtmlreactjs

解决方案


编辑:

这应该给你一个好主意:

https://stackblitz.com/edit/react-ts-cwm9ay?file=DynamicComponent.tsx

编辑#2:

我对 React 和插值非常擅长,它仍在进行中(特别是文档,但自述文件已完成)但我将无耻地插入我的ReactAST 库

编辑#3 - 如果您对进行疯狂的动态插值感兴趣,那么您可能还想查看一个简洁的动态插值(它是反向的)库

让我们假设:

{
   vars: ['name','surname'],
   strings: ["<p>Hello, how are you {name}?</p>","<p> It's night to meet you {name} {surname}"],
   inputs: {
      input1: 'name',
      input2: 'surname'
   }
}

创建一个可以执行此操作的组件(或一组组件)。

我什至没有运行任何这个,但这是这个想法。稍后我将把它放在一个堆栈闪电战中并对其进行润色以确保它可以正常工作:

const MyDynamicComponent = ({vars,strings,inputs}) => {
    const [state,setState] = useState(vars.reduce((acc,var) => ({...acc,[var]:undefined}));

     return (
        <>
         <MyDynamicText vars={vars} strings={strings} state={state}/>
         <MyDynamicInputs onChange={(name,val) => setState({[name]:val}) state={state} inputs={inputs}/>
        </>
     )
}

const MyDynamicText = ({vars,strings,state}) => {
   return strings.map((s,i) => s.replaceAll(`{${vars[i]}}`,state[vars[i]])
}

const MyDynamicInputs = ({onChange,inputs,state}) => {
   return Object.entries(inputs).map(([inputName,varName]) => <input key={inputName} onChange={e => onChange(varName,e.target.value)} value={state[varName]}/>
}

推荐阅读