本文是学习React笔记,对应视频为:https://www.bilibili.com/video/BV1oW41157DY 的 10 - 13 节。
一、组件组合使用
问题:数据保存在哪个组件内?
看数据时某个组件需要,还是某些组件需要?
问题2:在子组件中改变父组件的状态
子组件不能直接改变父组件状态
状态在那个组件,更新状态的行为就应该定义在哪个组件
父组件定义函数,传递给子组件
组件化编写功能的流程:
1. 拆分组件
2. 实现静态组件(只有静态界面,没有动态数据和交互)
3. 实现动态组件
1)实现初始化数据动态显示
2)实现交互功能
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SimpleList</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
<script src="babel.min.js"></script>
</head>
<body>
<div id="simple"></div>
<script type="text/babel">
class App extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {
todos: ['吃饭', '睡觉', '打代码']
}
this.addTodo = this.addTodo.bind(this)
}
addTodo(todo) {
const {todos} = this.state
todos.unshift(todo)
//更新状态
this.setState({
todos: todos
})
}
render() {
const {todos} = this.state
return (
<div>
<h1>Simple TODO List</h1>
<Add count={todos.length} addTodo={this.addTodo}/>
<List todos={todos}/>
</div>
)
}
}
class Add extends React.Component {
constructor(props) {
super(props);
this.add = this.add.bind(this)
}
add() {
//1. 读取输入的数据
const todo = this.todoInput.value.trim()
//2. 检查合法
if (!todo) {
return
}
//3. 添加
this.props.addTodo(todo)
//4. 清除
this.todoInput.value = ''
}
render() {
return (
<div>
<input type="text" ref={input => this.todoInput = input}/>
<button onClick={this.add}>add #{this.props.count + 1}</button>
</div>
)
}
}
Add.propTypes = {
count: PropTypes.number.isRequired,
addTodo: PropTypes.func.isRequired
}
class List extends React.Component {
render() {
const {todos} = this.props
return (
<ul>
{
todos.map((todo, index) => <li key={index}>{todo}</li>)
}
</ul>
)
}
}
List.propTypes = {
todos: PropTypes.array.isRequired
}
ReactDOM.render(<App/>, document.getElementById('simple'))
</script>
</body>
</html>
二、收集表单数据
需求:自定义包含表单的组件
1. 界面包含用户名和密码
2. 输入用户名密码后,点击登录提示信息
3. 不提交表单
包含表单的组件分类:
受控组件:表单输入数据能自动收集状态
非受控组件:需要是才手动读取表单输入框中的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form</title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prop-types/15.6.0/prop-types.js"></script>
<script src="babel.min.js"></script>
</head>
<body>
<div id="form"></div>
<script type="text/babel">
class LoginForm extends React.Component {
constructor(props) {
super(props);
//初始化状态
this.state = {
pwd: ''
}
this.handleSubmit = this.handleSubmit.bind(this)
this.handleOnChange = this.handleOnChange.bind(this)
}
handleSubmit(event) {
const name = this.nameInput.value
//用 {} 后相当于 const pwd = this.state.pwd
const {pwd} = this.state
alert(`准备提交的账号是:${name},密码是${pwd}`)
//阻止事件的默认行为(提交表单)
event.preventDefault()
}
handleOnChange(event) {
//读取输入的值
const pwd = event.target.value;
//更新pwd状态(pwd恰好一致可以省略 pwd:)
this.setState({pwd})
}
render() {
return (
<form action="/test" onSubmit={this.handleSubmit}>
用户名:<input type="text" ref={input => this.nameInput = input}/>
密码:<input type="password" value={this.state.pwd} onChange={this.handleOnChange}/>
<input type="submit" value="登录"/>
</form>
)
}
}
ReactDOM.render(<LoginForm/>, document.getElementById('form'))
</script>
</body>
</html>