У меня есть несколько строк с этим форматом:
'The model of that car is [assignment: any car model] and it has [assignment: any number] horsepower'
Я хочу отобразить эту строку в своем пользовательском интерфейсе и заменить каждое вхождение [custom: text] текстовым полем. Мой CustomComponent реализует текстовое поле с заполнителем. Я хочу, чтобы заполнителем был текст, который находится между «[custom:» и закрывающей квадратной скобкой.
Я использую responseStringReplace, чтобы заменить строковые шаблоны реагирующими компонентами. Основная проблема заключается в том, что реакция StringReplace заменит все совпадающие случаи одновременно. Даже если я сопоставлю только первое вхождение, это приведет к появлению нескольких флажков с одним и тем же заполнителем.
Я даже пытался сопоставить только одно вхождение, удаляя '/g' в конце регулярного выражения, но все равно все вхождения заменяются
Это мой код:
const reactStringReplace = require('react-string-replace');
const description = 'The model of that car is [custom: any car model] and it has [custom: any number] horsepower'
function formatString(input){
const regex = /\[assignment: (.*?)\]/g;
const regex_assignment = /\[assignment: (.*?)\]/;
let formattedString = input;
let match;
let placeholder;
let newString = input;
while ((match = regex.exec(input)) !== null) {
placeholder = match[1];
newString = reactStringReplace(newString,regex_assignment, ()=> (<CustomComponent placeholder = {placeholder}/>))
}
return(newString);
}
return (
<div class = 'description'>
<div>{formatString(description)}</div>
</div>
);



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Возвращаемое значение reactStringReplace — это массив, а не строка (и так должно быть, чтобы выполнять свою работу). Но вы рассматриваете это как строку.
Вам не обязательно иметь цикл в своем коде, это одна из вещей, которую reactStringReplace делает для вас, как показано в разделе «Более реалистичный пример». Так что все намного проще (я изменил регулярное выражение, чтобы использовать custom вместо assignment, поскольку это то, что находится в строке description):
function formatString(input) {
return reactStringReplace(input, /\[custom: (.*?)\]/g, (match, i) => (
<CustomComponent key = {i} placeholder = {match} />
));
}
(Это использование индекса для key, который обычно является анти-шаблоном [см. ловушку в этом разделе документации React], но я думаю, что выбор правильного ключа выходит за рамки вопроса.)
Живой пример:
const reactStringReplace = module.exports;
function formatString(input) {
return reactStringReplace(input, /\[custom: (.*?)\]/g, (match, i) => (
<CustomComponent key = {i} placeholder = {match} />
));
}
// Stand-in for CustomComponent
function CustomComponent({ placeholder }) {
return <span className = "placeholder">{placeholder}</span>;
}
function Example() {
const description =
"The model of that car is [custom: any car model] and it has [custom: any number] horsepower";
return (
<div className = "description">
<div>{formatString(description)}</div>
</div>
);
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Example />);.placeholder {
color: blue;
font-weight: bold;
}<div id = "root"></div>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.development.js"></script>
<script src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.development.js"></script>
<script>
const module = {};
</script>
<script src = "https://unpkg.com/[email protected]/index.js"></script>
Было бы здорово, если бы вы могли добавить результат, который хотите получить от этого. Я почти уверен, что вам не нужны дополнительные пакеты.