今天我遇到了在 React 中突出显示匹配括号的问题。这是示例文本:
(my text (is here and) I want (to highlight (something here)))
我希望它在代码编辑器中看起来像,我的意思是: image attached
我尝试使用 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>;
};
但我遇到了 react maximum update depth
的问题。
是否可以做得更简单,无需更新状态等?
答案 0 :(得分:1)
当然,一旦你知道了正确的工具,这并不难。
这是我创建的一个 CodeSandbox example,以及下面相同的片段(针对 Stack Overflow 的古老 Babel 版本稍作调整)。
想法是:
string.split
的正则表达式模式将字符串拆分为括号或不是括号的片段此示例中的颜色只有 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>