版权声明:转载请注明出处!喜欢就关注一下or点赞鼓励一下呗 https://blog.csdn.net/ImagineCode/article/details/82430370
今天我们来一个小练习,最常见的TODO练习,将组件进行组合使用。
首先明确以下3点:
功能界面的组件化编码流程(重要)
- 1、拆分组件:例如把一个整体界面进行拆分,分为一个个单个组件
- 2、实现静态组件:使用组件实现静态页面效果
- 3、实现动态苏建:动态显示初始化数据;实现交互功能,如绑定事件监听
思考?
- 数据应该保存在哪个组件内?
分析:
- 1、看数据是某个组件需要,还是某些组件需要。某个组件需要就保存在某个组件。某些组件需要就保存在这些组件共同的父组件中;
- 2、然后看数据是什么类型;
思考?
- 子组件中改变父组件的状态:不能在子组件中直接改变父组件的状态
- 方法:状态在哪个组件,更新状态的行为(函数)就应该定义在哪个组件
- 子组件去调用父组件的方法
- 父组件定义函数,传递给子组件,子组件进行调用
示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="test1"></div>
<div id="test2"></div>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<script src="../js/prop-types.js"></script>
<script type="text/babel">
//Todo List
//1、定义组件:将整体组件拆分为3个单个组件
//将<Add />与<List />组件放在<App />组件中,实现一个静态组件
//2、动态显示初始化数据——数据应该保存在哪个组件内
//3、添加交互,监听事件绑定
class App extends React.Component {
constructor(props){
super(props)
//初始化状态设置
this.state = {
todos: ['aaa','bbb','ccc']
}
this.addTodo = this.addTodo.bind(this);
}
addTodo(todo) {
const {todos} = this.state;
todos.unshift(todo);
//更新状态
this.setState({todos});
}
render() {
const {todos} = this.state;//解构赋值写法
return (
<div>
<h1>TODO LIST</h1>
<Add count={todos.length} addTodo={this.addTodo}/>
<List todos={todos}/>
</div>
)
}
}
class Add extends React.Component {
constructor(props){
super(props)
this.handleAdd = this.handleAdd.bind(this);
}
handleAdd() {
//1、读取输入的数据
const todo = this.inputVal.value.trim()
//2、检测合法性,合法则添加
if(!todo){
return
}
this.props.addTodo(todo);//因为addTodo被放在属性中传过来
this.inputVal.value='';
}
render() {
return (
<div>
<input type="text" ref={input => this.inputVal=input}/>
<button onClick={this.handleAdd}>增加 {this.props.count+1}</button>
</div>
)
}
}
Add.propTypes = {
count: PropTypes.number.isRequired,
addTodo:PropTypes.func.isRequired
}
class List extends React.Component {
render() {
return (
<ul>
{
this.props.todos.map((todo,index)=>{return <li key={index}>{todo}</li>})
}
</ul>
)
}
}
List.propTypes = {
todos: PropTypes.array.isRequired
}
ReactDOM.render(<App />,document.getElementById('test1'));
</script>
</body>
</html>
小结–组件组合编写的流程(记住流程)
- 1、拆分组件:根据页面结构拆分组件
- 2、实现静态组件:先给组件类指定render(),每个组件都指定。(此时没有动态数据与交互)
- 3、实现动态组件:先初始化数据的动态显示;然后再添加交互,绑定(bind)事件监听。
在组件中收集表单数据
实际工作中,我们常常需要操作表单数据,如向服务端提交表单数据要发送请求,如检验表单数据合法性,等等。。那么这些操作之前,首先我们需要收集到表单数据。
实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div id="test1"></div>
<script src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<script src="../js/prop-types.js"></script>
<script type="text/babel">
//1、定义类组件
class LoginForm extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {
psw : ''
}
this.handleSubmit = this.handleSubmit.bind(this);//绑定事件侦听
this.handleChange = this.handleChange.bind(this);//绑定事件侦听
}
handleSubmit(event) {
const name = this.nameInput.value;
const {psw} = this.state;
alert('username:'+name+' password:'+psw);
//阻止事件的默认行为
event.preventDefault();
}
//psw失去焦点事件
handleChange(event) {
//读取输入值
const psw = event.target.value;
//更新psw状态
this.setState({psw});
}
render() {
return (
<form action="" method="" onSubmit={this.handleSubmit}>
<label htmlFor="username">用户名:</label>
<input type="text" id="username" ref={input => this.nameInput = input}/>
<label htmlFor="psw">密码:</label>
<input type="password" id="psw" value={this.state.psw} onChange={this.handleChange}/>
<input type="submit" value="Login In"/>
</form>
)
}
}
//2、渲染组件
ReactDOM.render(<LoginForm/>,document.getElementById('test1'));
</script>
</body>
</html>
小结
包含表单的组件分为2类:
- 受控组件:表单项输入数据能自动收集成状态state,如password,读状态state
- 非受控组件: 需要时才手动读取表单的数据,如username,需要手动设置
大多数情况请,推荐使用“受控组件”来实现表单,比较符合React的思想,但是这两者的效率并没有太大的差异。