I'm working on a form in my ReactJs app. What I'd like to do:
1/ select a draft letter from an array of draft letters by its id // ok
2/ display the title, body and location of the selected draft letter in a form below // ok
3/ then the user should be able to edit all the fields // not ok!
This is what I did :
class NewLetter extends Component {
constructor(props) {
super(props)
this.state = {
city: "",
title: "",
letterBody: "",
}
this.handleChange_city = this.handleChange_city.bind(this);
this.handleChange_letterBody = this.handleChange_letterBody.bind(this);
this.handleChange_title = this.handleChange_title.bind(this);
}
handleChange_city(e) {
this.setState({
city: e.target.value
});
}
handleChange_letterBody(e) {
this.setState({
title: e.target.value
});
}
handleChange_title(e) {
this.setState({
letterBody: e.target.value
});
}
render() {
return (
<form className="containerLetter">
<div className="form-group">
<input type="text" className="form-control" id="letterLocation" placeholder="where are you?" value={this.props.city} onChange={this.handleChange_city}/>
</div>
<div className="form-group">
<input type="text" className="form-control" id="letterTitle" placeholder="give a title to your letter" value={this.props.title} onChange={this.handleChange_title} />
</div>
<div className="form-group">
<textarea type="text" className="form-control" id="letterBody" placeholder="Letter content" value={this.props.letterBody} onChange={this.handleChange_letterBody} />
</div>
<button className="actionButton">Send the letter</button> <br />
<button className="actionButton">Save as draft</button>
</form>
)
}
}
export default NewLetter
If I use value
, the fields are not editable
If I use defaultValue
the field are editable but when the defaultValue change, React doesn't re-render. The values are passed as props by the parent component:
class DraftLetters extends Component {
constructor(props) {
super(props)
this.state = {
selectedDraftIndex: 0,
};
this.handleChange = this.handleChange.bind(this);
}
getListOfDrafts = () => {
var list = []
for (let i = 0; i < this.props.drafts.length; i++) {
list.push(<option value={i}> {this.props.drafts[i].redactionDate} </option>);
}
return (list);
}
handleChange(e) {
this.setState({
selectedDraftIndex: e.target.value,
})
}
render() {
return (
<div >
{(this.props.drafts.length != 0) &&
<div className="form-group selectLetter">
<label for="sel1">Select the draft:</label>
<select onChange={this.handleChange} className="form-control" id="sel1">
{this.getListOfDrafts()}
</select>
</div>
}
{(this.props.drafts.length == 0) &&
<div className="form-group">
<p className="noLetter"> You haven't saved any draft.</p>
<img width="400px" className="img-fluid" src={painting} alt="tableau"></img>
</div>
}
<div>
<br />
{(this.props.drafts.length != 0) &&
<NewLetter city={this.props.drafts[this.state.selectedDraftIndex].city}
title={this.props.drafts[this.state.selectedDraftIndex].title}
letterBody={this.props.drafts[this.state.selectedDraftIndex].letterBody}></NewLetter>
}
{this.state.selectedDraftIndex}
</div>
</div>
)
}
}
export default DraftLetters
It seems to be a well known problem
This is what I found: defaultValue change does not re-render input
React input defaultValue doesn't update with state
https://github.com/facebook/react/issues/4101
Is there nowdays a fix for this problem?