[英]Child component sharing state with parent?
我对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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.