Reactjs React-更新具有默认值的受控元素
我已经到处找了,但似乎找不到解决这个问题的灵丹妙药 在我的应用程序中,我可以创建一个便条。我希望能够编辑/更新注释。音符的值通过道具传递。如何使用道具作为textarea的默认值,同时跟踪注释的新值Reactjs React-更新具有默认值的受控元素,reactjs,Reactjs,我已经到处找了,但似乎找不到解决这个问题的灵丹妙药 在我的应用程序中,我可以创建一个便条。我希望能够编辑/更新注释。音符的值通过道具传递。如何使用道具作为textarea的默认值,同时跟踪注释的新值 class Note extends Component { constructor(props) { super(props); this.state = { noteValue: '' }; this.saveNote = this.saveN
class Note extends Component {
constructor(props) {
super(props);
this.state = {
noteValue: ''
};
this.saveNote = this.saveNote.bind(this);
this.updateNote = this.updateNote.bind(this);
}
saveNote() {
// Saves the note
}
updateNote(e) {
this.setState({ noteValue: e.target.value });
}
render() {
console.log('ALREADY CREATED NOTE VALUE : ', this.props.note.value)
return (
<textarea
// defaultValue={this.props.note.value} I want to be able to do this but I know I can't since it's controlled
onChange={this.updateNote}
value={this.state.noteValue}
/>
<button onClick={this.saveNote}>Save</button>
);
}
}
function mapDispatchToProps(dispatch) {
return bindActionCreators({
updateNote: NoteActions.updateNote,
}, dispatch);
}
function mapStateToProps(state, props) {
return {
note: NoteSelectors.getNoteById(state, props)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Note);
类注释扩展组件{
建造师(道具){
超级(道具);
此.state={
注意值:“”
};
this.saveNote=this.saveNote.bind(this);
this.updateNote=this.updateNote.bind(this);
}
saveNote(){
//保存便条
}
更新日期(e){
this.setState({noteValue:e.target.value});
}
render(){
console.log('已创建注释值:',this.props.NOTE.VALUE)
返回(
拯救
);
}
}
功能图DispatchToprops(调度){
返回bindActionCreators({
updateNote:NoteActions.updateNote,
},派遣);
}
函数mapStateToProps(状态、道具){
返回{
注意:NoteSelectors.getNoteById(状态,道具)
}
}
导出默认连接(mapStateToProps、mapDispatchToProps)(注);
当字段/输入具有通过道具的默认值时,更新该字段/输入的最佳方法是什么
this.state={…this.props}
似乎不是正确的方法。所有的文章都说这是一种反模式getDerivedStateFromProps
感到非常困惑您可以使用
componentDidMount
方法
componentDidMount(){
this.setState({ noteValue : this.props.note.value})
}
当组件完成加载时,您可以将noteValue
设置为props
中的值,在这种情况下,您不需要设置defaultValue
,而value
属性将起作用
更新时,您可以使用setState
中的callback
将更新后的值发送到父组件
updateNote(e) {
this.setState({ noteValue: e.target.value }, () => //call function from parent to update the change);
}
我可以通过以下方式想出另一个解决方案:
this.state = {
noteValue: ''
};
....
<textarea
onChange={this.updateNote}
value={this.state.noteValue || this.props.note.value || ''}
/>
this.state={
注意值:“”
};
....
由于空字符串是falsy(
this.state.noteValue
),它将首先转到this.props.note.value
,如果不存在,它将以空字符串结束 实际上,getDerivedStateFromProps
生命周期方法正是针对这种情况的。它会监听组件道具的所有更改。每次道具改变都会触发。而且,您仍然应该在lifecycle方法中检查新需要的道具,以避免不必要地重新渲染
返回值充当React的setState
功能。它会立即更改组件的状态
class Note extends Component
{
static getDerivedStateFromProps(newProps, currentState)
{
console.log(newProps); // also you can listen the changes for simple debugging
if (newProps.noteValue !== currentState.noteValue)
{
return ({ noteValue: newProps.noteValue }); // it will make change the state with new prop value
}
return null; // if nothing changed
}
....
}
我也看到了这种方法,但它总是会在第一次加载时导致第二次渲染。在这一点上,我宁愿在构造函数中设置它来避免额外的渲染。在构造函数中设置道具状态可能会导致未定义道具的问题,因为当道具准备好时(考虑来自API调用的数据),您的子构造函数可能会先执行。是的,我确实遇到了这个问题,必须使用三元来检查数据。我对我目前的解决方案不满意,但我只是继续往下看了一会儿。在这种情况下,当用户开始在文本区域键入内容时,我似乎必须更新我的便笺(从redux商店提取)。在他们点击save之前,我不想更新任何内容。相反,我希望在状态中跟踪他们的更新。听道具对我没有任何好处,因为它应该保持不变,直到我发出API调用来更新注释。您将仅将本地状态更新为currentNote变量。当他们保存便笺时,会触发redux state,您将从
getDerivedStateFromProps
中以defaultNote的形式获取新状态。当我在textarea中键入时,它将更新this.state.noteValue
。这将导致getDerivedStateFromProps
中的if
语句触发。因此,值将始终是来自道具的值,文本区域文本将永远不会更改。我希望有帮助。我希望这个答案对你有所帮助。我认为如果小心使用,这是避免反模式的唯一方法。