反应组件。加载内容

时间:2018-05-10 09:46:23

标签: javascript reactjs ecmascript-6

我正在使用react在类中的fetch API调用的上下文中显示这样的组件中的一些文本。对loadContents的调用执行以下操作:

  • 获取原始HTML。
  • 使用React组件替换html元素,该组件显示放置在原始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. 调用loadContents('/contents1')下载html资源,并在通过handleClick按下链接时进行替换。
  2. loadContents('/contents2')也是如此:下载html资源并在通过handleClick按下链接时进行替换。
  3. ReactComp永远显示&#34; someTextPage1&#34;如果我加载first / contents1,即使我稍后加载/ contents2。如果我从/ contents2开始也是如此:&#34; someTextPage2&#34;将被加载到ReactComponent并且永远不会更改。当我按下链接时,其余的内容都正确加载,这只是React组件的问题。

1 个答案:

答案 0 :(得分:0)

事实证明,问题是如果key属性与前一个匹配,则即使加载的内容不同,也不会构造新的Component。 encounter()被重用。所以这段代码:

from random import randint


class Zombie(object):
    pass


class Ghul(object):
    pass


class Skeleton(object):
    pass


class Ghost(object):
    pass


class Slime(object):
    pass


class MobFactory(object):
    # create() function will return a mob depending of roll value
    @staticmethod
    def create(roll):
        if roll <= 5:
            return Zombie()
        elif roll <= 10:
            return Ghul()
        elif roll <= 15:
            return Skeleton()
        elif roll <= 19:
            return Ghost()
        else:
            return Slime()


def encounter():
    roll = randint(1, 20)
    mob = MobFactory.create(roll)
    print(mob.__class__)


if __name__ == '__main__':
    # Here I simulate multiple call of encounter()
    for _ in range(0, 3):
        encounter()

当加载两个页面但键匹配时,不会创建ReactComp的新实例,而是重新使用它。解决方案是在ReactComp中使用以下内容:

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

当没有创建新实例时,这将刷新现有组件并更改属性。