【问题标题】:Passing a function to a button within dangerouslySetInnerHTML doesn't work将函数传递给危险SetInnerHTML 中的按钮不起作用
【发布时间】:2021-06-24 14:46:41
【问题描述】:

当在 react 中找到模式时,我试图在文本之间添加一个按钮标签,这是在 dangerouslySetInnerHTML 属性中完成的。 onClick 仅适用于 alert() 和 console.log(),当我将函数传递给它时它不起作用。我错过了什么?

    export const detectHashTagPattern = (text) => {
      if(!text) return '';
      let pattern = /This is a follow-up to your previous request #[0-9]+/gi;
      let hashTagPattern = /#[0-9]+/;
    
      text = text.replace(pattern, (res) => {
        return res.replace(hashTagPattern, `<button onClick={}>${hashTagPattern.exec(res)}</button>`);
      });

  return text;
};

【问题讨论】:

  • 关于您的问题:window 对象中是否存在该函数?但是,如果您找到了模式,更好的解决方案可能是将字符串拆分为一个数组。然后通过迭代来渲染它。通过拥有一个数组,您可以完全避免使用dangerouslySetInnerHTML
  • 函数已经存在。不使用 dangerouslySetInnerHTML 的方法只渲染组件,我想从 [object Object] 调用方法
  • 所以目标是当检测到特定模式时,将模式文本转换为按钮组件,单击该按钮组件时,会打开一个模式以显示一些信息

标签: javascript reactjs dangerouslysetinnerhtml


【解决方案1】:

你可以像下面这样改变算法:


function clickHandler() {
  console.log("do something");
}

window.clickHandler = clickHandler;

export const detectHashTagPattern = (text) => {
  if (!text) return "";
  let pattern = /This is a follow-up to your previous request #[0-9]+/gi;
  let hashTagPattern = /#[0-9]+/;

  text = text.replace(pattern, (res) => {
    return res.replace(
      hashTagPattern,
      // use window.<fct>()
      `<button onClick="window.${window.clickHandler.name}()">${hashTagPattern.exec(
        res
      )}</button>`
    );
  });

  return text;
};

您不应该采用这种方法,因为它可能在您的应用程序中呈现其他问题(取决于您在处理程序中执行的操作)。

更好的方法是这样的:

const splitSubject = (text) => {
  if (!text) {
    return [""];
  }

  let pattern = /This is a follow-up to your previous request #[0-9]+/gi;

  if (!pattern.test(text)) {
    return [text];
  }
  let hashTagPattern = /#[0-9]+/;
  let result = text.search(hashTagPattern);
  return [text.slice(0, result), text.slice(result), text.slice(result + 1)];
};

const Subject = ({ subject, handler }) => {
  const splitted = splitSubject(subject);

  let content = null;
  if (splitted.length === 1) {
    content = <span>{splitted[0]}</span>;
  } else {
    let [info, cmd, reqReference] = splitted;

    content = (
      <>
        <span>{info}</span>
        <button onClick={() => handler?.(reqReference)}>{cmd}</button>
      </>
    );
  }

  return <p>{content}</p>;
};

export default function App() {
  const requestHandler = (num) => {
    console.log(`click on '${num}'`);
  };

  return (
    <div>
      <Subject
        handler={requestHandler}
        subject="This is a follow-up to your previous request #9"
      />
      <Subject handler={requestHandler} subject="Not matching subject" />
    </div>
  );
}


【讨论】:

  • 第一种方法会抛出未捕获的引用错误:在 HTMLButtonElement.onclick 中未定义 clickHandler。但是,对于第二种方法,检测到的模式之后的以下文本也显示为按钮
  • 第一种方法现在有效,非常感谢。如果需要,您会如何建议我将参数传递给 clickHandler() 并在 onClick 中调用它?
  • 参见方法 2。处理程序的工作方式与此完全相同。您也可以查看stackoverflow.com/questions/10000083/…
  • 所以,我尝试通过将函数作为参数传递来扩展第一种方法,以便可以从任何其他文件调用它 export const detectHashTagPattern = (text, handleEvent) => { if (!text) return ""; let pattern = /这是你之前请求的后续 #[0-9]+/gi;让 hashTagPattern = /#[0-9]+/; text = text.replace(pattern, (res) => { return res.replace( hashTagPattern, &lt;button onClick="${handleEvent.name}()"&gt;${hashTagPattern.exec( res )}&lt;/button&gt;... 我得到一个 Uncaught SyntaxError: Unexpected token ')'
猜你喜欢
  • 2021-12-21
  • 2021-12-11
  • 2019-04-26
  • 2015-12-25
  • 1970-01-01
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
相关资源
最近更新 更多