在 React 中更新状态时的问题
Problems when updating state in React
请查看我的 js fiddle 我在其中说明了问题
这是我的 js fiddle:
https://jsfiddle.net/jajabya/fb93f7b0/
我的目标是获得一个 input
标签,其中可以通过包裹在 span
标签中来突出显示特殊词(例如日期或用户名)
div
肯定有问题,因为当我改用输入字段时一切正常。
我的问题是我无法使插入符号出现在正确的位置
每次状态更新 onInput
onInput(event) {
this.setState({
html: event.target.innerText.toUpperCase()
});
}
插入符号回滚到开头
我的想法是保存状态中的当前插入符号位置,并通过 componentDidUpdate()
中的 ref 将其设置回来(因为 ref 不会重新渲染组件)。
注意:这是一个原型想法,我从未进行过战斗测试,因此请谨慎使用。
插入符号位置代码取自以下答案:
Code for getting the caret position
Code for setting caret position
class Editable extends React.Component {
componentDidUpdate(prev) {
const { position } = this.props;
if(position !== prev.position && this.ce.childNodes.length) {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(this.ce.childNodes[0], position);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
render() {
return (
<div
contentEditable
className={this.props.className}
onInput={this.props.onInput}
ref={ce => this.ce = ce}
suppressContentEditableWarning>
{this.props.html}
</div>
);
}
}
class App extends React.Component {
state = {
html: 'Text',
caret: 0
};
handleInput = (event) => this.setState({
html: event.target.innerText.toUpperCase(),
position: window.getSelection().getRangeAt(0).startOffset
});
render() {
return (
<Editable
{...this.state}
className="Editable"
onInput={this.handleInput} />
);
}
}
ReactDOM.render(
<App />,
demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="demo"></div>
请查看我的 js fiddle 我在其中说明了问题
这是我的 js fiddle: https://jsfiddle.net/jajabya/fb93f7b0/
我的目标是获得一个 input
标签,其中可以通过包裹在 span
标签中来突出显示特殊词(例如日期或用户名)
div
肯定有问题,因为当我改用输入字段时一切正常。
我的问题是我无法使插入符号出现在正确的位置
每次状态更新 onInput
onInput(event) {
this.setState({
html: event.target.innerText.toUpperCase()
});
}
插入符号回滚到开头
我的想法是保存状态中的当前插入符号位置,并通过 componentDidUpdate()
中的 ref 将其设置回来(因为 ref 不会重新渲染组件)。
注意:这是一个原型想法,我从未进行过战斗测试,因此请谨慎使用。
插入符号位置代码取自以下答案:
Code for getting the caret position
Code for setting caret position
class Editable extends React.Component {
componentDidUpdate(prev) {
const { position } = this.props;
if(position !== prev.position && this.ce.childNodes.length) {
const range = document.createRange();
const sel = window.getSelection();
range.setStart(this.ce.childNodes[0], position);
range.collapse(true);
sel.removeAllRanges();
sel.addRange(range);
}
}
render() {
return (
<div
contentEditable
className={this.props.className}
onInput={this.props.onInput}
ref={ce => this.ce = ce}
suppressContentEditableWarning>
{this.props.html}
</div>
);
}
}
class App extends React.Component {
state = {
html: 'Text',
caret: 0
};
handleInput = (event) => this.setState({
html: event.target.innerText.toUpperCase(),
position: window.getSelection().getRangeAt(0).startOffset
});
render() {
return (
<Editable
{...this.state}
className="Editable"
onInput={this.handleInput} />
);
}
}
ReactDOM.render(
<App />,
demo
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="demo"></div>