-
Notifications
You must be signed in to change notification settings - Fork 320
非受控组件
司徒正美 edited this page Jun 2, 2017
·
1 revision
表单元素如果指定了value/checked属性,但没有指定其他控制value/checked改变的其他属性(如onClick, onInput, onChange, disabled, readOnly),那么它将成为非受控组件。用户无法通过输入,点击或选择来改变此元素的value/checked或下拉框的option的selected值。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script type='text/javascript' src="./dist/React.js"></script>
<script src="./test/babel.js"></script>
<script type='text/babel'>
var textarea, radio, text, select, checkbox
window.onload = function(){
class Text extends React.Component{
constructor(props) {
super(props);
this.state={value:'Hello'};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
render() {
var value = this.state.value;
return <input type="text" value={this.state.value} />;
}
}
class Checkbox extends React.Component{
constructor(props) {
super(props);
this.state={checked: false};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({checked: event.target.checked});
}
render() {
var value = this.state.value;
return <input type="checkbox" name='xxx' checked={this.state.checked} />;
}
}
class Radio extends React.Component{
constructor(props) {
super(props);
this.state={checked: false};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({checked: event.target.checked});
}
render() {
var value = this.state.value;
return <input type="radio" name='xxx' checked={this.state.checked} />
}
}
class TextArea extends React.Component{
constructor(props) {
super(props);
this.state={value: 'dddd'};
this.handleChange=this.handleChange.bind(this);
}
handleChange(event) {
this.setState({value: event.target.checked});
}
render() {
return <textarea value={this.state.value}></textarea>
}
}
class Select extends React.Component {
constructor() {
super()
this.state = {
value: 'bbb'
}
}
render() {
return <select id='node8' value={this.state.value}>
<option value='aaa'>aaa</option>
<option value='bbb'>bbb</option>
<option value='ccc'>ccc</option>
</select>
}
}
text = ReactDOM.render(
<Text />,
document.getElementById('text')
)
checkbox = ReactDOM.render(
<Checkbox />,
document.getElementById('checkbox')
)
radio = ReactDOM.render(
<Radio />,
document.getElementById('radio')
)
textarea = ReactDOM.render(
<TextArea />,
document.getElementById('textarea')
)
select = ReactDOM.render(
<Select />,
document.getElementById('select')
)
}
</script>
</head>
<body>
<div>各种非受控组件</div>
<div id='text'></div>
<div id='checkbox'></div>
<div id='radio'></div>
<div id='textarea'></div>
<div id='select'></div>
</body>
</html>
``html
<script type='text/javascript' src="./dist/React.js"></script> <script type='text/javascript' src="./test/react.development.js"></script> <script type='text/javascript' src="./test/react-dom.development.js"></script><script type='text/javascript' src="./lib/babel.js"></script>
<pre>应该等于
</pre>
<h1 id='root' class="root">
</h1>
<script type='text/babel'>
var container = document.getElementById("example")
var div = container
var PropTypes = React.PropTypes
if(!window.ReactDOM){
window.ReactDOM = React
}
var expect = function(a) {
return {
toBe: function(b) {
console.log(a,"vs", b, a === b)
},
toEqual(b){
console.log(a,"vs", b, a +""=== b+"")
},
toThrow(b){
try{
a()
}catch(e){
console.log(e,"vs", b, e.message +""=== b+"")
}
}
}
}
const Hello = ({ name }) => <h1>Hello {name}!</h1>;
class ShowMyError extends React.Component {
constructor(props) {
super(props);
this.state = { error: false };
}
componentDidCatch(error, info) {
console.log(error, info)
this.setState({ error, info });
}
render() {
if (this.state.error) {
return (
<div>
<h1>
Error AGAIN: {this.state.error.toString()}
</h1>
{this.state.info &&
this.state.info.componentStack.split("\n").map(i => {
return (
<div key={i}>
{i}
</div>
);
})}
</div>
);
}
return this.props.children;
}
}
class Broken extends React.Component {
constructor(props) {
super(props);
this.state = { throw: false, count: 0 };
}
render() {
if (this.state.throw) {
throw new Error("YOLO");
}
return (
<div>
<button
onClick={e => {
this.setState({ throw: true });
}}
>
button will render error.
</button>
<button onClick={e => {
this.setState(({ count }) => ({
count: count + 1
}));
}}>button will not throw</button>
<div>
{"All good here. Count: "}{this.state.count}
</div>
</div>
);
}
}
class App extends React.Component {
render() {
const styles = {
fontFamily: "sans-serif",
textAlign: "center"
};
return (
<div style={styles}>
<Hello name="ShowMyError" />
<h2>
Start clicking to see some {"\u2728"}magic{"\u2728"}
</h2>
<ShowMyError>
<Broken />
</ShowMyError>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));