[英]How do I make a React component editable?
在我的學習反應和firebase項目的最后階段,我遇到了一個問題。 通過閱讀這兩本文檔,我已經了解了大部分內容以及如何做。
我想從博客文章中獲取內容,然后編輯它並使用
update()
方法firebase有。 截至目前,我面臨的兩個錯誤是我無法編輯該內容,因為反應表明它是一個受控元素,我從文檔中理解是因為我將其作為值傳遞。
但是,當我嘗試刪除它,而是在onInputChange中創建一個setState,就像文檔建議的那樣,它會更新,但是內容空白,原始文本也會從輸入字段中丟失。 這意味着我做錯了反應,但我不確定它是什么。
constructor(props){ super(props); this.state = { title: '', body: '', post:{}, }; this.onInputChange = this.onInputChange.bind(this); this.onHandleUpdate = this.onHandleUpdate.bind(this); } componentDidMount(){ database.ref(`posts/${this.props.match.params.postId}`) .on('value', snapshot => { this.setState({post: snapshot.val()}); }); this.postId= this.props.match.params.postId; } onInputChange(e){ this.setState({ title: '', body:'' }); } onHandleUpdate(e){ console.log(this.postId); e.preventDefault(); database.ref('posts').child(`${this.postId}`).update(this.state); this.setState({ title: '', body: '' }); } render() { return ( <div className="container"> <form onSubmit={this.onHandleUpdate}> <div className="form-group"> <input value={this.state.title && this.state.post.title} className="form-control" type="text" name="title" ref="title" onChange={this.onInputChange}/> </div> <br/> <div className="form-group"> <input value={this.state.body && this.state.post.body} className="form-control" type="text" name="body" ref="body" onChange={this.onInputChange} /> <br/> </div> <button className="btn btn-success">Submit</button> </form> </div> ); } }
這就是目前代碼的設置方式。 問題摘要簡單歸結為我無法更改文本框中的值的原因。 我做錯了什么?
如果您想在輸入中創建輸入可編輯的受控輸入,請使用值創建輸入並更改該值:
<input
type="text"
value={this.state.title}
onChange={e => this.handleInputChange(e)}
/>
在上面的代碼中,您已經定義了一對onChange處理程序,但是您沒有將事件傳遞給它們,因此它們永遠不會有任何數據可供使用。
對於我的例子,我的onChange處理程序可能是:
handleInputChange(e) {
this.setState({
title: e.target.value
});
}
每當我輸入我的輸入時,它將改變組件的狀態,這將改變我在輸入中看到的內容。 這有點間接,但這就是受控組件的反應方式。
如果你添加一個新的輸入,那么你可以創建一個新的onChange處理程序,一切都應該正常工作。 然而,這種方法變得復雜。 創建一個包含10個輸入的表單,突然間您可以在組件中處理大量功能。
一種更易於管理的方法是創建一個與每個輸入組件一起使用的onChange處理程序。 您可以通過將要更新的狀態字段的名稱傳遞給函數來創建它。
handleChange(e, field) {
this.setState({
[field]: e.target.value
});
}
然后在您的輸入中,您可以像這樣使用它:
<input
type="text"
value={this.state.title}
onChange={e => this.handleChange(e, "title")}
/>
field參數是您希望更新輸入的狀態字段的字符串。
這意味着您可以為身體輸入重復使用相同的方法,如下所示:
type="text"
value={this.state.body}
onChange={e => this.handleChange(e, "body")}
/>
您可以刪除onTitleChange和onBodyChange方法,並使用上面的handleChange方法替換它們。 更簡單。 移動部分越少,破壞的東西就越少。
當您准備好提交表單時,您可以在onHandleUpdate方法中使用所需的狀態值,如下所示:
onHandleUpdate(e){
e.preventDefault();
database.ref('posts').child(`${this.postId}`).update({
title: this.state.title,
body: this.state.body
});
this.setState({
title: '',
body: ''
});
}
沒有必要使用狀態中的post值執行整個嵌套操作。 你可以偎依在心里,但是當你還在學習的時候,只要你能保持在國家中不嵌套,就能讓事情變得容易理解。
database.ref(`posts/${this.props.match.params.postId}`)
.on('value', snap => this.setState({
title: snap.val().title,
body: snap.val().body
}));
我做了一個小沙箱來證明這一切都有效。 看看這里的hello組件 。 我已經簡化了一點,我不得不更換數據庫調用(因為我沒有你的firebase密鑰),但它應該有意義。
因為它們是兩個單獨的字段值,您需要在兩個單獨的函數中處理它們。 你不能在onInputChange
使用相同的方法。 您可以更改以下代碼。
constructor(props){
super(props);
this.state = {
post:{
title: props.post.title || '',
body: props.post.body|| '',
},
};
this.onTitleChange = this.onTitleChange .bind(this);
this.onBodyChange = this.onBodyChange .bind(this);
this.onHandleUpdate = this.onHandleUpdate.bind(this);
}
componentDidMount(){
database.ref(`posts/${this.props.match.params.postId}`)
.on('value', snapshot => {
this.setState({post: snapshot.val()});
});
this.postId= this.props.match.params.postId;
}
onTitleChange(e){
this.setState({
post: { ...this.state.post,
title: e.target.value}
});
}
onBodyChange(e){
this.setState({
post: { ...this.state.post,
body: e.target.value}
});
}
onHandleUpdate(e){
console.log(this.postId);
e.preventDefault();
database.ref('posts').child(`${this.postId}`).update(this.state);
this.setState({
title: '',
body: ''
});
}
render() {
return (
<div className="container">
<form onSubmit={this.onHandleUpdate}>
<div className="form-group">
<input value={this.state.post.title} className="form-control" type="text" name="title" ref="title" onChange={this.onTitleChange}/>
</div>
<br/>
<div className="form-group">
<input value={this.state.post.body} className="form-control" type="text" name="body" ref="body" onChange={this.onBodyChange} />
<br/>
</div>
<button className="btn btn-success">Submit</button>
</form>
</div>
);
}
或者如果state是從componentDidMount設置的,那么你的構造函數可能是這樣的
constructor(props){
super(props);
this.state = {
post: null, //hope you post contains title and body {title: 'sometitle', body: 'somebody'}
};
您可以使用相同的方法處理更改
handleChange = (e) => { this.setState({ [e.target.name]: e.target.value }) }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.