我对React很新,我在第一个任务上有点挣扎。
我正在创建一个通用的TextBox(来自MaterialUI)组件,我创建了一个扩展TextBox的子组件(NumberInput)。问题是每当我在NumberInput中输入任何输入时,NumberInput状态似乎都不会更新。任何提示将不胜感激!
家长:
import React, { Component } from 'react';
import TextField from '@material-ui/core/TextField';
import { Validations } from './validations'
import PropTypes from 'prop-types';
class TextBox extends Component {
constructor(props) {
super(props);
this.state = {
value: null,
error: false,
errorMsg: null
};
this.setValue = this.setValue.bind(this);
this.setError = this.setError.bind(this);
this.setErrorMsg = this.setErrorMsg.bind(this);
this.handleChange = this.handleChange.bind(this);
this.checkForErrors = this.checkForErrors.bind(this);
}
// Handles changes upon each edit of the textbox. Updates the state value and checks for errors.
handleChange(event) {
this.setValue(event);
}
setValue(event) {
var value = document.getElementById(this.props.id).value;
this.setState({ value: value }, () => this.checkForErrors());
}
setError(error, errorMsg) {
this.setState({ error: error });
this.setErrorMsg(errorMsg);
}
setErrorMsg(errorMsg) { this.setState({ errorMsg: errorMsg }) }
getValue() { return this.state.value }
getError() { return this.state.error }
getErrorMsg() { return this.state.errorMsg }
// Checks for input error
checkForErrors() {
var input = this.getValue();
console.log(input);
var validations = Validations(this.props, input);
this.setError(validations.error, validations.errorMsg);
}
render() {
let {
label,
placeholder,
maxLength,
minLength,
maxNumber,
minNumber,
disabled,
required,
type,
multiline,
id,
name,
allowSpecialCharacters,
allowWhitespace
} = this.props;
return (
<div>
<br/>
<TextField
error = { this.getError() }
label = { label }
helperText = { this.getErrorMsg() }
placeholder = { placeholder }
inputProps = {{ maxLength: maxLength }}
disabled = { disabled }
required = { required }
type = { type }
multiline = { multiline }
onChange = { this.handleChange }
id = { id }
name = { name }
/>
</div>
);
}
};
TextBox.propTypes = {
label: PropTypes.string,
helperText: PropTypes.string,
placeholder: PropTypes.string,
maxLength: PropTypes.number,
minLength: PropTypes.number,
maxNumber: PropTypes.number,
minNumber: PropTypes.number,
disabled: PropTypes.bool,
required: PropTypes.bool,
type: PropTypes.oneOf(["button", "checkbox", "color", "date", "datetime-local", "email", "file",
"hidden", "image", "month", "number", "password", "radio", "range", "reset", "search",
"submit", "tel", "text", "time", "url", "week"]),
multiline: PropTypes.bool,
id: PropTypes.string,
name: PropTypes.string,
allowSpecialCharacters: PropTypes.bool,
allowWhitespace: PropTypes.bool
}
TextBox.defaultProps = {
label: '',
helperText: '',
placeholder: '',
maxLength: 100000,
minLength: 0,
maxNumber: 100000,
minNumber: -100000,
disabled: false,
required: false,
type: 'text',
multiline: false,
id: 'input',
name: '',
allowSpecialCharacters: true,
allowWhitespace: true
}
export default TextBox;
儿童:
import React, { Component } from 'react';
import TextBox from './textbox';
import { Validations } from './validations'
import PropTypes from 'prop-types';
// const NumberInput = props => {
// return (
// <TextBox {...props} type="number" />
// )
// }
class NumberInput extends TextBox {
constructor(props) {
super(props);
this.state = {
value: null,
error: false,
errorMsg: null
};
}
render() {
return (
<div>
<TextBox
label = { "NumberInput" }
type = { "number" }
/>
</div>
)
}
};
export default NumberInput;
App.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
import TextBox from './widgets/textbox/textbox';
import TextArea from './widgets/textbox/textarea';
import NumberInput from './widgets/textbox/numberinput';
class App extends Component {
render() {
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to
reload.
</p>
<TextBox type="text" label={"Textbox"} />
<NumberInput label={"NumberInput"} />
</div>
);
}
}
export default App;
更新了NumberInput
:
const NumberInput = props => {
return (
<TextBox {...props} type="number" id="inp" />
)
}
您不需要在此处为您的子组件使用类,并从父组件扩展它。将处理函数传递给子组件时,此过程非常简单。
class Parent extends React.Component {
state = {
value: "initial value",
}
handleChange = e => this.setState({ value: e.target.value });
render() {
return (
<div>
<p>Change the value:</p>
<Child onChange={this.handleChange} value={this.state.value} />
<p>{JSON.stringify(this.state.value)}</p>
</div>
);
}
}
const Child = props => {
return (
<input onChange={props.onChange} value={props.value} />
)
}
ReactDOM.render(<Parent />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>