问题
I come from Angular and jquery before that. Seems that how state, props, contructors, ComponentDidMount etc.. are owning me.
I simply have a Textarea that I want to end up json stringify the form data to on button click to set to the json, but i will even settle for just having the function set the textarea value.
import React from 'react';
export default class ClinicalMain extends React.Component {
constructor(props) {
super(props);
}
state = {
selectedOption : ''
}
// my function to update the textarea
reactStringify() {
let obj = {
name:"bob",
age: 4
}
console.log('in stringify');
let value = JSON.stringify(obj);
}
componentDidMount() {
}
render() {
return (
<React.Fragment>
<form>
<button type="button" onClick={this.reactStringify} id="reactid">React stringify</button>
<textarea value={this.value} defaultValue="" rows="10" cols="80"></textarea><br />
</form>
</React.Fragment>
)
}
}
let value just does not update. Do I need to use setState? this?
回答1:
There are a number of issues in the code indicating a lack of familiarity with the excellent React tutorial. As with any library, it's necessary to spend time reading the manual before diving in.
State should not be modified directly. Use
this.setState()to modify state.this.setState()doesn't work instantly; it simply informs the React library that the state needs updating and React handles the update on its own when it sees fit.Beyond this,
let value = ...is a purely local variable, not a class variable, sothis.valuewould be undefined inrenderno matter what; in other words, the above code doesn't attempt to modify or accessstatein any way.Class functions that attempt to access
thisneed to be bound. For example,onClick={this.reactStringify}passes a reference to thethis.reactStringifyfunction, butthiswill be undefined inside ofthis.reactStringifyunless an arrow function is used (which implicitly bindsthis), orthisis explicitly bound:this.handleChange = this.handleChange.bind(this);Explicit is considered to be better practice for class components than the arrow function approach because it only requires one call to
bind.React typically uses something called controlled components to listen to changes on a text field. This means that the element's value tracks component state and acts as the single source of truth.
While I'm not exactly sure what you're ultimately looking to accomplish, here's a working example to get you moving again which demonstrates the above concepts.
class ClinicalMain extends React.Component {
constructor(props) {
super(props);
this.state = {value: ""};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(e) {
this.setState({value: e.target.value});
}
handleSubmit(e) {
e.preventDefault();
this.setState({
output: `you wrote: "${this.state.value}"`
});
}
render() {
return (
<React.Fragment>
<form onSubmit={this.handleSubmit}>
<textarea
value={this.state.value}
onChange={this.handleChange}
></textarea>
<input type="submit" value="Show output" />
</form>
<div>{this.state.output}</div>
</React.Fragment>
);
}
}
ReactDOM.render(
<ClinicalMain name="World" />,
document.getElementById("app")
);
input {
display: block;
}
form {
margin-bottom: 0.4em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Here are relevant sections of the documentation which provide more detail:
- State and Lifecycle
- Handling Events
- Forms
来源:https://stackoverflow.com/questions/57580026/set-textarea-value-to-text-or-json-of-data-properly-in-a-function