Reactjs 危险的赛汀能不能';渲染期间不更新

Reactjs 危险的赛汀能不能';渲染期间不更新,reactjs,Reactjs,因此,我制作了一个组件,用于在我的应用程序中包含内容可编辑组件。我从一些我相信的要点中复制了它,然后编辑成我所需要的 代码如下。当我编辑它时,它会在父级上触发更新,但当我尝试在父级中设置props.html时,它不会反映在UI中。 此外,console.log显示this.props.html等于“”一个空白字符串,但UI不更新,并维护最初在其中的文本 我不明白这怎么可能。。。DangerouslySetinerHTML={uuuuHTML:''}应使其成为空字符串,以便UI反映空字符串。。。感

因此,我制作了一个组件,用于在我的应用程序中包含内容可编辑组件。我从一些我相信的要点中复制了它,然后编辑成我所需要的

代码如下。当我编辑它时,它会在父级上触发更新,但当我尝试在父级中设置props.html时,它不会反映在UI中。 此外,console.log显示this.props.html等于“”一个空白字符串,但UI不更新,并维护最初在其中的文本

我不明白这怎么可能。。。DangerouslySetinerHTML={uuuuHTML:''}应使其成为空字符串,以便UI反映空字符串。。。感觉它不可能显示旧文本

var React = require('react');

var ContentEditable = React.createClass({
    render: function(){
        //TODO: find where html=undefined and fix it! So I can remove this? Maybe I should keep this safety.
        var html = this.props.html || '';
        console.log('content editable render, html: ', this.props.html);
        return <div id="contenteditable"
            onInput={this.emitChange} 
            onBlur={this.emitChange}
            contentEditable
            dangerouslySetInnerHTML={{__html: html}}></div>;
    },
    shouldComponentUpdate: function(nextProps){
        return nextProps.html !== this.getDOMNode().innerHTML;
    },

    emitChange: function(){
        var html = this.getDOMNode().innerHTML;
        if (this.props.onChange && html !== this.lastHtml) {
            this.props.onChange({
                target: {
                    value: html
                }
            });
        }
        this.lastHtml = html;
    }
});

module.exports = ContentEditable;
var React=require('React');
var ContentEditable=React.createClass({
render:function(){
//TODO:找到html=undefined的位置并修复它!这样我就可以删除它了?也许我应该保持安全。
var html=this.props.html | |“”;
log('内容可编辑呈现,html:',this.props.html);
返回;
},
shouldComponentUpdate:函数(下一步){
返回nextrops.html!==this.getDOMNode().innerHTML;
},
emitChange:function(){
var html=this.getDOMNode().innerHTML;
if(this.props.onChange&&html!==this.lastHtml){
这个。道具。改变({
目标:{
值:html
}
});
}
this.lastHtml=html;
}
});
module.exports=内容可编辑;

(一点背景知识,在提交要保存的输入后,我正试图清除它。清除不起作用,因此出现了这个问题。)

我在使用
contentEditable
shouldComponentUpdate时遇到了一个非常类似的问题,当使用
危险的SetinerHTML
函数(或prop)将innerHTML重置为相同的先前值时,似乎存在错误(我认为即使您插入代码而不使用它,它也无法工作)。。。我怀疑(这只是一个想法),React会将通过
DangerouslySetinerHTML
设置的最后一个值与您尝试发送的新值进行比较,并决定不更新组件,因为它是相同的(即使真实的innerHtml由于用户交互而改变,因为这些交互不会在React上触发任何状态或道具更新)

解决方案:我找到的最简单的解决方案是每次需要重新渲染时使用不同的键。例如使用
key={Date()}

示例:您可以找到您的代码(我更改了部分代码以使其正常工作),当您在div中键入“?”时,ContentEditable组件中的文本应成为空字符串(即“”),它只工作一次,第二次键入“?”将不工作,因为react的innerHTML与您正在设置的相同(即,一个空字符串,因此它不会更新组件)


并且,我添加了
键={Date()}
(这是向您展示此功能的最简单方法,但不是每次重新渲染时设置唯一键的最佳方法)对于可编辑组件,现在您可以键入任意数量的“?”,它将起作用。

我找到了另一种可能比生成随机键更好的解决方案。将键专门放在调用#DangerouslySetinerHTML的div上,而不仅仅放在组件本身上

<div class='wrapper'>    
<div key={this.props.thing.id} dangerouslySetInnerHtml={this.props.thing.content} />
</div>

我遇到了同样的问题(React 16),并使用了一种建议的方法,即删除
危险的SetinenerHTML
,并使用
componentDidMount()
代替初始渲染,并使用
componentDidUpdate()
进行任何后续渲染

此处的溶液,适于反应16:

这些钩子将执行相同的更新,直接从props更新
innerHTML

componentDidMount() {
  this.updateInnerHTMLFromProps();
}

componentDidUpdate() {
  this.updateInnerHTMLFromProps();
}

updateInnerHTMLFromProps() {
  this.refEl.innerHTML = this.props.html;
}
这使得(至少对我来说)能够更清楚地了解到底发生了什么,而不会像这里建议的那样错误地期望
危险的setinenerHTML
会在所有情况下保持DOM同步

有关问题的完整视图以及此处列出的两种解决方案,请查看。

我的(非常简单)React(版本16)应用程序:它有一个
可编辑的
。
点击提交按钮后,它成功地重新呈现了这个
。我使用
ref={el=>this.myRefElem=el}
componentWillUpdate(nextProps){this.myRefElem.innerHTML=nextProps.myInputText;}
对于我来说,
nextrops
对于重新渲染正确的值很重要。请查看我的应用程序的项目文件,以查看其余所需的代码。
​ 查看我的React应用程序。它有一个按钮可以下载(开发模式)项目文件。它(基本上)只有一个index.js文件。---这个应用程序是由谁启动的,他要求我提供一种替代技术。

通常,任何可能更改的数据都应该放在父级的状态中,子级应该使用从父级状态传下来的道具,这样,一旦编辑父级的状态,React将重新呈现子级。这就是p详细说明我是如何尝试这样做的。旁注:
TODO:find where html=undefined并修复它!
。尝试
console.log('html undefined',new Error().stack)
我有类似的类型,然后按reset,它不会重置。将下一个props.html包装在新字符串()中会使它工作/4出于某种原因,
key={Date()}
对我不起作用,但使用Math.random()可以。即使我设置了其他状态,我也看到了这个问题。例如,我尝试了
this.setState({edited:true})
onInput
处理程序中,然后在
componentdiddupdate
中编辑:false
。我假设问题存在,除非新状态成为新元素的一部分,例如作为属性。对我来说仍然像是一个bug。无论如何,添加属性