ReactJS 组件文本区域未在状态更改时更新
ReactJS component textarea not updating on state change
我正在尝试编写笔记 taking/organizing 应用程序,但 运行 遇到了一个令人沮丧的错误。
这是我的组件:
import React from 'react';
const Note = (props) => {
let textarea, noteForm;
if (props.note) {
return (
<div>
<button onClick={() => {
props.handleUpdateClick(props.selectedFolderId, props.selectedNoteId, textarea.value);
}}>
Update
</button>
<textarea
defaultValue={props.note.body}
ref={node => {textarea = node;}}
/>
</div>
);
} else {
return <div></div>;
}
};
export default Note;
就目前而言,每当我在笔记之间切换并使用 note.body 道具中的新内容重新渲染笔记组件时,textarea 不会更改并保留前一个笔记的内容。我已经尝试对文本区域使用 value 属性而不是 defaultValue 属性,这确实解决了组件重新呈现时文本区域内容不更改的问题,但是当我这样做时,我不再能够在 textarea 字段中键入更新笔记
有没有人知道我既可以允许用户在文本字段中键入以更新注释,又可以在呈现不同注释时更改文本区域内容的方法?
谢谢
问题在于,将值设置为您的 prop 会导致组件的所有 re-renders 使用相同的 prop,因此新文本会被删除。一种解决方案是将文本保留在组件的本地状态中。要同时收听道具变化,您可以在收到新道具时设置状态。
const Note = React.createClass({
getInitialState() {
return {
text : this.props.note.body
}
},
componentWillReceiveProps: function(nextProps) {
if (typeof nextProps.note != 'undefined') {
this.setState({text: nextProps.note.body });
}
},
render() {
if (this.props.note) {
return (
<div>
<button onClick={(e) => {
// Fire a callback that re-renders the parent.
// render(this.textarea.value);
}}>
Update
</button>
<textarea
onChange={e => this.setState({ text : e.target.value })}
value={this.state.text}
ref={node => {this.textarea = node;}}
/>
</div>
);
} else {
return <div></div>;
}
}
});
https://jsfiddle.net/69z2wepo/96238/
如果您使用的是 redux,您还可以对输入的更改事件触发操作以触发 re-render。您可以在减速器中保留输入值。
因为 componentWillReceiveProps
现在不安全 Max Sindwani 的回答现在有点过时了。
试试这些步骤:
- 将您的组件转换为 class
- 现在您可以包含
shouldComponentUpdate()
生命周期钩子
- 创建您的事件处理程序并将其传递给 onChange
在 <textarea>
中,您可以将 defaultValue
属性换成 value
(只需在处理程序中使用 event.preventDefault(),以便用户可以如果需要继续更新文本)
import React from 'react';
export class Note extends React.Component {
constructor(props) {
super(props);
this.state={text: this.props.note.body}
}
shouldComponentUpdate(nextProps) {
if(nextProps.note.body !== this.state.text) {
this.setState({text: nextProps.note.body})
return true;
}
return false;
}
updateText = (event) => {
event.preventDefault();
this.setState({text: nextProps.note.body});
}
render() {
if (this.props.note) {
return (
<div>
<textarea
onChange={this.updateText}
value={this.state.text}
name={'display'}
/>
</div>
);
} else {
return <div></div>;
}
}});
我正在尝试编写笔记 taking/organizing 应用程序,但 运行 遇到了一个令人沮丧的错误。
这是我的组件:
import React from 'react';
const Note = (props) => {
let textarea, noteForm;
if (props.note) {
return (
<div>
<button onClick={() => {
props.handleUpdateClick(props.selectedFolderId, props.selectedNoteId, textarea.value);
}}>
Update
</button>
<textarea
defaultValue={props.note.body}
ref={node => {textarea = node;}}
/>
</div>
);
} else {
return <div></div>;
}
};
export default Note;
就目前而言,每当我在笔记之间切换并使用 note.body 道具中的新内容重新渲染笔记组件时,textarea 不会更改并保留前一个笔记的内容。我已经尝试对文本区域使用 value 属性而不是 defaultValue 属性,这确实解决了组件重新呈现时文本区域内容不更改的问题,但是当我这样做时,我不再能够在 textarea 字段中键入更新笔记
有没有人知道我既可以允许用户在文本字段中键入以更新注释,又可以在呈现不同注释时更改文本区域内容的方法?
谢谢
问题在于,将值设置为您的 prop 会导致组件的所有 re-renders 使用相同的 prop,因此新文本会被删除。一种解决方案是将文本保留在组件的本地状态中。要同时收听道具变化,您可以在收到新道具时设置状态。
const Note = React.createClass({
getInitialState() {
return {
text : this.props.note.body
}
},
componentWillReceiveProps: function(nextProps) {
if (typeof nextProps.note != 'undefined') {
this.setState({text: nextProps.note.body });
}
},
render() {
if (this.props.note) {
return (
<div>
<button onClick={(e) => {
// Fire a callback that re-renders the parent.
// render(this.textarea.value);
}}>
Update
</button>
<textarea
onChange={e => this.setState({ text : e.target.value })}
value={this.state.text}
ref={node => {this.textarea = node;}}
/>
</div>
);
} else {
return <div></div>;
}
}
});
https://jsfiddle.net/69z2wepo/96238/
如果您使用的是 redux,您还可以对输入的更改事件触发操作以触发 re-render。您可以在减速器中保留输入值。
因为 componentWillReceiveProps
现在不安全 Max Sindwani 的回答现在有点过时了。
试试这些步骤:
- 将您的组件转换为 class
- 现在您可以包含
shouldComponentUpdate()
生命周期钩子 - 创建您的事件处理程序并将其传递给 onChange
在
<textarea>
中,您可以将defaultValue
属性换成value
(只需在处理程序中使用 event.preventDefault(),以便用户可以如果需要继续更新文本)import React from 'react'; export class Note extends React.Component { constructor(props) { super(props); this.state={text: this.props.note.body} } shouldComponentUpdate(nextProps) { if(nextProps.note.body !== this.state.text) { this.setState({text: nextProps.note.body}) return true; } return false; } updateText = (event) => { event.preventDefault(); this.setState({text: nextProps.note.body}); } render() { if (this.props.note) { return ( <div> <textarea onChange={this.updateText} value={this.state.text} name={'display'} /> </div> ); } else { return <div></div>; } }});