<!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>hello_react</title>
<!-- 引入react,为了使用 React对象 -->
<script src="js/react.development.js"></script>
<!-- 引入 react-dom, 为了使用 ReactDOM 对象 -->
<script src="js/react-dom.development.js"></script>
<!-- 引入 babel, 为了 解析 JSX -->
<script src="js/babel.min.js"></script>
<!-- 引入prop-types,为了对 props属性的类型、必要性、默认值进行限制,全局多了一个 PropTypes对象 -->
<script src="js/prop-types.js"></script>
</head>
<body>
<div id="test"></div>
<!-- 1. 非受控组件 -->
<!-- <script type="text/babel">
class Login extends React.Component {
handleSubmit = (event) => {
event.preventDefault() // event是事件对象。调用事件对象的preventDefault。可以阻止默认事件。因为提交是表单的默认事件。
const {username, password} = this
alert(`你输入的用户名是:${username.value},你输入的密码是${password.value}`)
// 表单提交默认引发页面的跳转。
// 为了更好的用户体验,我们希望能够页面不刷新发送ajax请求。所以需要阻止表单跳转。
// 1.删除表单的action属性,并不能解决问题。页面依然进行了刷新,且表单中填写的数据消失了。
// 2.利用原生的阻止默认事件---可以阻止表单提交
}
render() {
return (
// <form action="http://atguigu.com" onSubmit={this.handleSubmit}>
<form onSubmit={this.handleSubmit}>
用户名:<input ref={c => this.username = c } type="text" name="username"/>
密码:<input ref={c => this.password = c } type="password" name="password"/>
<button>登录</button>
</form>
)
}
// 非受控组件:表单中输入类DOM的值,比如input,checkbox,radio等,现用现取-----非受控。
}
ReactDOM.render(<Login/>, document.getElementById('test'))
</script> -->
<!-- 2. 受控组件 -->
<!-- <script type="text/babel">
class Login extends React.Component {
// 初始化状态
state = {
username: '',
password: ''
}
// 保存用户名到状态中
saveUsername = (event) => {
this.setState({username: event.target.value})
}
// 保存密码到状态中
savePassword = (event) => {
this.setState({password: event.target.value})
}
// 表单提交的回调
handleSubmit = (event) => {
event.preventDefault()
const {username, password} = this.state
alert(`你输入的用户名是:${username},你输入的密码是${password}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
用户名:<input onChange={this.saveUsername} type="text" name="username"/>
密码:<input onChange={this.savePassword} type="password" name="password"/>
<button>登录</button>
</form>
)
}
// 受控组件:页面中所有输入类的DOM,比如input,radio等,随着你的输入能够把输入的东西维护到状态中去。
// 等需要用的时候,直接从状态中取出来。-----受控组件。
// 类似于 vue 中双向绑定。
// 建议大家写:受控组件。因为受控组件中一个ref都没有用。react明确提出,勿过度使用ref。
}
ReactDOM.render(<Login/>, document.getElementById('test'))
</script> -->
<!-- 3. 高阶函数 -->
<!-- <script type="text/babel">
class Login extends React.Component {
state = {
username: '',
password: ''
}
// 保存表单数据到状态中
saveFormData = (dataType) => {
// saveFormData函数的返回值,不再是undefined,而是另一个函数。这个函数才是onChange真正的回调函数。
return (event) => { // 这里的event是react在调用onChange回调时,传入的事件对象。
this.setState({
[dataType]: event.target.value // 对象中所有的属性名都是字符串。 读变量的方式: [变量]
})
}
}
/* 概念: saveFormData就是一个高阶函数。
高阶函数:如果一个函数符合下面2个规范中的任何一个,那该函数就是高阶函数
1. 若A函数,接收的参数是一个函数,则A函数就可以称为高阶函数
2. 若A函数,调用的返回值依然是一个函数,则A函数就是高阶函数
saveFormData 的返回值是一个函数,所以它是高阶函数。
常见的高阶函数有: Promise、 setTimeout(() => {}, 1000)、 arr.map(() => {})
函数的柯里化:通过函数调用继续返回函数的方式,实现多次接收参数,最后统一处理的函数编码形式。
*/
// 表单提交的回调
handleSubmit = (event) => {
event.preventDefault()
const {username, password} = this.state
alert(`你输入的用户名是:${username},你输入的密码是${password}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
{/*一再强调:回调函数后面不要写小括号。---否则会直接调用这个回调函数。
且 onChange={this.saveFormData('username')} 代码的含义是:
将saveFormData函数的返回值给了onChange作为回调。
不是将saveFormData交给onChange作为回调。
而saveFormData的返回值是 undefined。
onChange={this.saveFormData} 含义是:把saveFormData函数交给onChange作为回调。当input框输入值发生改变时,react会自动帮你调用saveFormData。
所以,不加小括号是真的把一个函数交给onChange作为回调,而加小括号是把一个函数的返回值交给onChange作为回调。特别不巧saveFormData的返回值偏偏也undefined。
解决办法:让saveFormData的返回值不是undefined,而是一个函数。
原则:必须把一个函数交给onChange作为回调。
*/}
用户名:<input onChange={this.saveFormData('username')} type="text" name="username"/>
密码:<input onChange={this.saveFormData('password')} type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login/>, document.getElementById('test'))
</script> -->
<!-- 4.对象相关的知识 -->
<!-- <script type="text/javascript">
let a = "name"
let obj = {}
obj[a] = "tom"
console.log(obj) // {name: "tome"}
</script> -->
<!-- 5.函数的柯里化 -->
<!-- <script type="text/javascript">
// 1. 函数没有使用柯里化
// function sum(a, b, c) {
// return a+b+c
// }
// const result = sum(1,2,3)
// console.log(result)
// 2.函数的柯里化
function sum(a) {
return (b) => {
return (c) => {
return a + b +c
}
}
}
const result = sum(1)(2)(3)
console.log(result)
</script> -->
<!-- 6.不用柯里化的实现:同时接收dataType参数与event事件对象 -->
<script type="text/babel">
class Login extends React.Component {
state = {
username: '',
password: ''
}
saveFormData = (dataType, event) => {
this.setState({
[dataType]: event.target.value
})
}
handleSubmit = (event) => {
event.preventDefault()
const {username, password} = this.state
alert(`你输入的用户名是:${username},你输入的密码是${password}`)
}
render() {
return (
<form onSubmit={this.handleSubmit}>
{/*注意:在onChange的回调函数中,去调用saveFormData函数,并给saveFormData传两个参数。
onChange的回调函数是:匿名的箭头函数。在react中,这个匿名的箭头函数可以接收到event事件对象。这个event事件对象是react传递进去的。
我们的做法是:在这个匿名的箭头函数中,通过 this.saveFormData()形式调用 saveFormData函数并传递参数。
而匿名的箭头函数中的 saveFormData此时就可以接收到 event对象。所以我们可以通过这种形式,传递event对象的同时,给自定义函数传递其他参数。
*/}
用户名:<input onChange={ event => this.saveFormData('username', event)} type="text" name="username"/>
密码:<input onChange={ event => this.saveFormData('password', event)} type="password" name="password"/>
<button>登录</button>
</form>
)
}
}
ReactDOM.render(<Login/>, document.getElementById('test'))
</script>
</body>
</html>