state-form
1. 受控组件
外来数据props/自己维护的状态state发生改变的时候,会导致组件的视图重新渲染,页面发生改变;这种组件受状态和属性变化的控制,称之为受控组件。
特点:数据驱动(数据更新,页面就跟着更新),不用直接操作DOM。
2. 不受控组件
组件不受状态和属性变化的控制,称之为不受控组件。
特点:可以操作DOM(类似于传统的html表单操作),通过ref。
3. 模拟受控表单(简单版本)
<script type="text/babel">
class App extends React.Component {
state = { name: "", age: 18 }
handleClick = () => {
console.log('form data:', this.state);
}
render() {
return (
<div>
name:
<input type="text" value={this.state.name} />
<button onClick={this.handleClick}>commit</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("app"));
</script>
- 当点击按钮时,虽然得到了数据,但是会报错
– 这是因为,react不同于vue,不具有双向绑定- input 两个方向:属性绑定 和 事件绑定
即:value: state => input
input => state (需要onChange)
<script type="text/babel">
class App extends React.Component {
state = { name: "", age: 18 }
handleClick = () => {
console.log('form data:', this.state);
}
hanleChange=(e)=>{
console.log(e.target.value);
this.setState({
name:e.target.value
})
}
render() {
return (
<div>
name:
<input type="text" value={this.state.name} onChange={this.hanleChange}/>
<button onClick={this.handleClick}>commit</button>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById("app"));
</script>
* 受控表单 => state,value 和 onChange,form 关系
- onChange,form进行同步,将state数据同步到表单中;
- form中的数据通过onChange传递回来,state中的数据通过value传过去
4. 模拟受控表单(复杂版本=>form中有多种数据输入)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 挂载容器 -->
<div id="app"></div>
<!-- 引入库 -->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class App extends React.Component {
state = { name: "user", age: 18,single:false,desc:'introduction',hobby:'playing' }
handleSubmit = (e) => {
//搜集表单数据
console.log('form data:', this.state);
//阻止默认行为
e.preventDefault();
}
hanleChange1=(e)=>{
console.log(e.target.value);
this.setState({
name:e.target.value
})
}
hanleChange2=(e)=>{
console.log(e.target.value);
this.setState({
age:e.target.value
})
}
hanleChange3=(e)=>{
console.log(e.target.checked);
this.setState({
single:e.target.value
})
}
hanleChange4=(e)=>{
console.log(e.target.value);
this.setState({
desc:e.target.value
})
}
hanleChange5=(e)=>{
console.log(e.target.value);
this.setState({
hobby:e.target.value
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
name:<input type="text" value={this.state.name} onChange={this.hanleChange1}/><br/>
age:<input type="number" value={this.state.age} onChange={this.hanleChange2}/><br/>
single:<input type="checkbox" value={this.state.single} onChange={this.hanleChange3}/><br/>
desc:<textarea value={this.state.desc} onChange={this.hanleChange4}></textarea><br/>
<select name="" value={this.state.hobby} onChange={this.hanleChange5}>
<option value="eatting">吃</option>
<option value="playing">玩</option>
<option value="sleeping">睡</option>
</select>
<input type="submit" value="commit" />
</form>
)
}
}
ReactDOM.render(<App />, document.getElementById("app"));
</script>
</body>
</html>
5. 优化:模拟受控表单(复杂版本=>form中有多种数据输入)
- 根据4,我们可以看出:hanleChange1——hanleChange5有很多相似的地方
- 不同之处:
key动态 , value:e.target.value 注意:e.target.checked
this.setState({
key:value
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 挂载容器 -->
<div id="app"></div>
<!-- 引入库 -->
<script src="../js/react.development.js"></script>
<script src="../js/react-dom.development.js"></script>
<script src="../js/babel.min.js"></script>
<script type="text/babel">
class App extends React.Component {
state = { name: "user", age: 18,single:false,desc:'introduction',hobby:'playing' }
handleSubmit = (e) => {
//搜集表单数据
console.log('form data:', this.state);
//阻止默认行为
e.preventDefault();
}
handleChange=(e)=>{
let target = e.target
let key = target.name
let type = target.type
let value = target.value
//注意:checkbox
let value = type=='checkbox'?target.checked:target.value
// this.setState({
// key:value //key写死了,相当于给原来的对象中追加了一个key,值为value
// })
this.setState({
[key]:value //key动态的
})
}
render() {
return (
<form onSubmit={this.handleSubmit}>
name:<input type="text" name="name" value={this.state.name} onChange={this.hanleChange}/><br/>
age:<input type="number" name="age" value={this.state.age} onChange={this.hanleChange}/><br/>
single:<input type="checkbox" name="single" value={this.state.single} onChange={this.hanleChange}/><br/>
desc:<textarea name="desc" value={this.state.desc} onChange={this.hanleChange}></textarea><br/>
<select name="name" value={this.state.hobby} onChange={this.hanleChange}>
<option value="eatting">吃</option>
<option value="playing">玩</option>
<option value="sleeping">睡</option>
</select>
<input type="submit" value="commit" />
</form>
)
}
}
ReactDOM.render(<App />, document.getElementById("app"));
</script>
</body>
</html>