简体   繁体   English

Javascript/react - 高亮匹配括号

[英]Javascript/react - highlight matching parenthesis

today I faced a problem with highlighting matching parenthesis in React.今天我遇到了在 React 中突出显示匹配括号的问题。 This is example text:这是示例文本:

(my text (is here and) I want (to highlight (something here)))

And I want it to look like in code editor, I mean: image attached我希望它在代码编辑器中看起来像,我的意思是:附加图片

I tried to use react-process-string :我尝试使用react-process-string

 processString([ { regex: /\\(|\\)/g, fn: (key, result) => this.colorBracket(key, result[0]) } ])(value); colorBracket = (key, result) => { const { usedColors } = this.state; const bracketColors = ['red', 'green', 'yellow', 'blue', 'purple']; let newColor = ''; if (result === '(') { newColor = usedColors.length ? bracketColors[usedColors.length] : bracketColors[0]; if (!usedColors.includes(newColor)) { this.setState({ usedColors: [...usedColors, newColor] }); } } else { newColor = usedColors.length ? usedColors[usedColors.length - 1] : bracketColors[0]; if (usedColors.length) { this.setState({ usedColors: usedColors.filter(e => e !== newColor) }); } } return <span style={{ color: newColor }}>{result}</span>; };

but I faced problem with react maximum update depth .但我遇到了react maximum update depth

Is it possible to do it more simple, without updating state and so on?有没有可能做得更简单,而不更新状态等等?

Sure thing, it's not really hard at all once you know the right tools.当然,一旦你知道了正确的工具,这并不难。

Here's a CodeSandbox example I whipped up, and a snippet of the same below (slightly adjusted for Stack Overflow's ancient Babel version).这是我创建的CodeSandbox 示例,以及以下相同的片段(针对 Stack Overflow 的古老 Babel 版本稍作调整)。

The idea is:这个想法是:

  • use string.split 's regexp mode to split the string into fragments that are either brackets or aren't使用string.split的正则表达式模式将字符串拆分为括号或不是括号的片段
  • iterate over those fragments to keep track of the nesting level for the brackets (to properly colorize pairs)迭代这些片段以跟踪括号的嵌套级别(以正确着色对)
  • finally, return a React fragment with those children (this way we don't have to deal with array keys)最后,返回一个带有这些子元素的 React 片段(这样我们就不必处​​理数组键了)

The colors in this example are only 3 levels deep, but you could easily add more, or make the colorization loop over N colors using the modulus operator.此示例中的颜色只有 3 级深,但您可以轻松添加更多级别,或使用模数运算符在 N 种颜色上进行着色循环。

 function BracketHighlighter({ text }) { const children = React.useMemo(() => { const out = []; let level = 0; text.split(/([()])/).forEach((bit) => { if (bit === "(") { level++; out.push(<span className={"l" + level}>{bit}</span>); } else if (bit === ")") { out.push(<span className={"l" + level}>{bit}</span>); level--; } else { out.push(bit); } }); return out; }, [text]); return React.createElement(React.Fragment, {}, ...children); } function App() { const [text, setText] = React.useState( "(my text (is here and) I want (to highlight (something here)))" ); return ( <div className="App"> <input value={text} onChange={(e) => setText(e.target.value)} /> <br /> <BracketHighlighter text={text} /> </div> ); } ReactDOM.render(<App />, document.getElementById("root"));
 .l1 { background-color: orange; } .l2 { background-color: lightgreen; } .l3 { background-color: cyan; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.0/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.0/umd/react-dom.production.min.js"></script> <div id="root"></div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM