Реагировать компонент. Не отображается правильное значение после загрузки содержимого - PullRequest
0 голосов
/ 10 мая 2018

Я использую реагирование для отображения некоторого текста в таком компоненте в контексте вызова API извлечения внутри класса. Вызов loadContents делает следующее:

  • Получить необработанный HTML.
  • заменить элемент html компонентом React, показывающим некоторый текст, который был помещен в исходный html, и показывающим этот компонент вместе с остальной частью исходного html.

Проблема, которую я получаю, состоит в том, что текст правильно извлекается в переменной myText, но впоследствии некорректно отображается в компоненте React:

handleClickLink(event) {
    const simpleHttpRegex = new RegExp(`https?://[a-zA-z0-9:_.]+\(/.*)`);
    var match = simpleHttpRegex.exec(event.target.href);
    if (match != null) {
        event.stopPropagation();
        event.preventDefault();
        this.loadContents(match[1], true);
    }
    else {
        console.log('Regular expression did not match url');
    }
}



loadContents() {
fetch(url,
      ...).then(response => response.text())
            .then((responseBody) => {
                this.state.myTexts = [];
                const parser = new DOMParser();
                const dom = parser.parseFromString(responseBody, "text/html");
                const content = dom.getElementById('content');
                let preTags = Array.from(content.getElementsByTagName('pre'));
                preTags.forEach(
                    (v) => {
                        if (v.classList.contains('someclass')) {
                            this.state.myTexts.push(v.innerText);
                        }
                    }, this);
                const serializedContent = (new XMLSerializer()).serializeToString(content);
                let i = 0;
                const replaceDivs = (node, index) => {     
                    if (node.type === 'tag' && node.name == 'div'
                             && ('class' in node.attribs) &&
                             node.attribs['class'] === 'someclass2') {
                        const myText = this.state.myTexts[i];
                        i++;
                        return <ReactComp key={'comp' + i.toString()} text={myText}/>;
                    }
                    return undefined;
                };
          const componentFromResponse = 
                 ReactHtmlParser(serializedContent, {transform: 
                  replaceDivs});
            this.setState({pageContents: componentFromResponse});
}   
  1. call loadContents('/contents1') загружает html ресурс и производит замену при нажатии на ссылку через handleClick.
  2. То же самое относится и к loadContents('/contents2'): загрузите html-ресурс и произведите замену, нажав на ссылку через handleClick.

ReactComp всегда показывает «someTextPage1», если я загружаю сначала / contents1, даже если я загружаю позже / contents2. То же самое происходит, если я запускаю через / contents2: «someTextPage2» будет загружен в ReactComponent и никогда не будет изменен. Остальное содержимое загружается правильно, когда я нажимаю на ссылки, проблема заключается только в компоненте React.

1 Ответ

0 голосов
/ 11 мая 2018

Оказывается, проблема в том, что не новый Компонент создается, если атрибут ключа совпадает с предыдущим, даже если загруженное содержимое отличается.ReactComp используется повторно.Таким образом, этот код:

return <ReactComp key={'comp' + i.toString()} text={myText}/>;

, когда две страницы загружены, но ключ совпадает, не создает новый экземпляр ReactComp, но повторно использует его.Решение состоит в том, чтобы использовать в ReactComp следующее:

static getDerivedStateFromProps(nextProps, prevState) {
    if (prevState.text != nextProps.text) {
        return {value : nextProps.text};
    }
    return null;
}

Это обновит существующий компонент изменениями свойств, когда новый экземпляр не создан.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...