菜单
一、ref的三种方式
- 字符串形式Ref
- 内联函数形式Ref
- 官方推荐createRef
1.1 字符串形式Ref
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
showData = ()=>{
const {input1} = this.refs;
console.log("showdata:"+input1.value+",Class:"+input1.className+',fieldValue:'+input1.getAttribute('data-field'));
}
showData2 = ()=>{
const input2 = this.refs.input2;
console.log("showdata2"+input2.value+",Class:"+input2.className+',fieldValue:'+input2.getAttribute('data-field'));
}
render(){
return (
<div>
<input ref="input1" data-field="123" className="input1Class" type="text" placeholder="clickShowData" />
<button onClick={this.showData}>show data</button>
<input ref="input2" data-field="234" className="input2Class" onBlur={this.showData2} type="text" placeholder="clickShowData2"/>
</div>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Demo />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
1.2 内联函数形式Ref
1.2.1 行内内联回调函数(不建议)
行内内联回调函数会在状态更新时重新调用,下面通过例子说明
先来一个简单的例子
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
showData = ()=>{
const {input1} = this;
console.log("showdata:"+input1.value+",Class:"+input1.className+',fieldValue:'+input1.getAttribute('data-field'));
}
render(){
return (
<div>
<input ref={(c)=>{this.input1=c}} data-field="123" className="input1Class" type="text" placeholder="clickShowData" />
{/**<input ref={(c) => { this.input2 = c; }} data-field="456" className="input2Class" type="text" placeholder="clickShowData" />
<input ref={c => this.input3 = c } data-field="789" className="input3Class" type="text" placeholder="clickShowData" /> **/}
<button onClick={this.showData}>show data</button>
</div>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Demo />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
现在我们在上述例子增加一个状态变更(state)
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
state = { showType:false}
showData = ()=>{
const {input1} = this;
console.log("showdata:"+input1.value+",Class:"+input1.className+',fieldValue:'+input1.getAttribute('data-field'));
}
changeShowtype = ()=>{
const {showType} = this.state;
console.log("@"+showType)
this.setState({showType:!showType});
}
render(){
const {showType} = this.state;
return (
<div>
<h1>1{showType?'显示':'隐藏'}1</h1>
<input ref={(c)=>{this.input1=c;console.log("@222");}} data-field="123" className="input1Class" type="text" placeholder="clickShowData" />
<button onClick={this.showData}>show data</button>
<button onClick={this.changeShowtype}>changeShowtype</button>
</div>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Demo />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
通过例子后,我们发现会调用两次。可以通过下面的例子进行修复
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
state = { showType:false}
showData = ()=>{
const {input1} = this;
console.log("showdata:"+input1.value+",Class:"+input1.className+',fieldValue:'+input1.getAttribute('data-field'));
}
saveInput1 = (c)=>{
this.input1 = c;
console.log("showdata: " + this.input1.value + ", Class: " + this.input1.className );
console.log(222);
}
changeShowtype = ()=>{
const {showType} = this.state;
console.log("@"+showType)
this.setState({showType:!showType});
}
render(){
const {showType} = this.state;
return (
<div>
<h1>1{showType?'显示':'隐藏'}1</h1>
<input ref={this.saveInput1} data-field="123" className="input1Class" type="text" placeholder="clickShowData" />
<button onClick={this.showData}>show data</button>jj
<button onClick={this.changeShowtype}>changeShowtype</button>
</div>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Demo />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
1.3 createRef形式
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Demo extends React.Component{
input1Ref = React.createRef();
input2Ref = React.createRef();
showData = ()=>{
const input1 = this.input1Ref.current;
console.log("showdata:"+input1.value+",Class:"+input1.className+',fieldValue:'+input1.getAttribute('data-field'));
}
showData2 = ()=>{
const input2 = this.input2Ref.current;
console.log("showdata2:"+input2.value+",Class:"+input2.className+',fieldValue:'+input2.getAttribute('data-field'));
}
render(){
return (
<div>
<input ref={this.input1Ref} data-field="123" className="input1Class" type="text" placeholder="clickShowData" />
<button onClick={this.showData}>show data</button>
<input ref={this.input2Ref} data-field="234" className="input2Class" onBlur={this.showData2} type="text" placeholder="clickShowData2"/>
</div>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Demo />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
二、受控组件和非受控组件
2.1受控组件
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
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:${username},password:${password}`);
// 构建表单数据对象
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
// 获取 form 元素并提交表单
const form = event.target;
form.action = 'http://example.com/submit'; // 设置表单提交的 URL
form.method = 'POST'; // 设置表单提交的方法
form.submit(); // 提交表单
}
render(){
return (
<form onSubmit={this.handleSubmit}>
username:<input onChange={this.saveUsername} type="text" name="username" /><br/>
password:<input onChange={this.savePassword} type="password" name="password" /><br/>
<button>submit</button>
</form>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Login />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
2.2通过受控组件来实现ajax
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
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:${username},password:${password}`);
// 构建表单数据对象
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
// 发送表单数据到服务器
fetch('http://example.com/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// 处理服务器响应
console.log(data);
})
.catch(error => {
// 处理错误
console.error(error);
});
}
render(){
return (
<form onSubmit={this.handleSubmit}>
username:<input onChange={this.saveUsername} type="text" name="username" /><br/>
password:<input onChange={this.savePassword} type="password" name="password" /><br/>
<button>submit</button>
</form>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Login />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
扩展学习-对象
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<script type="text/javascript">
let a = "filed1"
let obj = {};
obj[a]='value';
console.log(obj)
</script>
</body>
</html>
通过上述的例子,我们可以优化上面例子中的onchange例子
优化1:内联回调函数
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Login extends React.Component{
state = {
username:'',
password:''
}
saveFormData = (datatype,event)=>{
console.log("upload1")
this.setState({[datatype]:event.target.value})
}
handleSubmit = (event)=>{
event.preventDefault (); //组织表单提交
const {username,password} = this.state;
alert(`username:${username},password:${password}`);
// 构建表单数据对象
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
// 发送表单数据到服务器
fetch('http://example.com/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// 处理服务器响应
console.log(data);
})
.catch(error => {
// 处理错误
console.error(error);
});
}
render(){
return (
<form onSubmit={this.handleSubmit}>
username:<input onChange={event =>this.saveFormData('username',event)} type="text" name="username" /><br/>
password:<input onChange={event =>this.saveFormData('password',event)} type="password" name="password" /><br/>
<button>submit</button>
</form>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Login />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
优化2:内联函数
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Login extends React.Component{
state = {
username:'',
password:''
}
saveFormData = (datatype)=>{
console.log("upload2")
return (event)=>{
this.setState({[datatype]:event.target.value})
}
}
handleSubmit = (event)=>{
event.preventDefault (); //组织表单提交
const {username,password} = this.state;
alert(`username:${username},password:${password}`);
// 构建表单数据对象
const formData = new FormData();
formData.append('username', username);
formData.append('password', password);
// 发送表单数据到服务器
fetch('http://example.com/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// 处理服务器响应
console.log(data);
})
.catch(error => {
// 处理错误
console.error(error);
});
}
render(){
return (
<form onSubmit={this.handleSubmit}>
username:<input onChange={this.saveFormData('username')} type="text" name="username" /><br/>
password:<input onChange={this.saveFormData('password')} type="password" name="password" /><br/>
<button>submit</button>
</form>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Login />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>
2.3非受控组件
<!Doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<!-- 准备好一个容器 -->
<div id="test"></div>
<!--引入React 核心库-->
<script type="text/javascript" src="https://cdn.bootcss.com/react/16.4.0/umd/react.development.js"></script>
<!--引入React-dom 用于支持React操作DOM-->
<script type="text/javascript" src="https://cdn.bootcss.com/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!--引入babel 用于Jsx转换称js-->
<script type="text/javascript" src="https://cdn.bootcss.com/babel-standalone/6.26.0/babel.min.js"></script>
<!--引入prop-->
<script type="text/javascript" src="https://cdn.bootcss.com/prop-types/15.6.1/prop-types.js"></script>
<script type="text/babel">
//1、创建组件
class Login extends React.Component{
handleSubmit = (event)=>{
event.preventDefault (); //组织表单提交
const username = this.refs.username;
const {password} = this;
console.log(this);
alert(`username:${username.value},password:${password.value}`);
// 构建表单数据对象
const formData = new FormData();
formData.append('username', username.value);
formData.append('password', password.value);
// 发送表单数据到服务器
fetch('http://example.com/submit', {
method: 'POST',
body: formData
})
.then(response => response.json())
.then(data => {
// 处理服务器响应
console.log(data);
})
.catch(error => {
// 处理错误
console.error(error);
});
}
render(){
return (
<form onSubmit={this.handleSubmit}>
username:<input ref="username" type="text" name="username" /><br/>
{/** username:<input ref={(c)=>{this.username=c;}} type="text" name="username" /><br/> **/}
password:<input ref={c => this.password = c} type="password" name="password" /><br/>
<button>submit</button>
</form>
)
}
}
//2、渲染虚拟DOM到页面
ReactDOM.render(<Login />,document.getElementById('test'))
/*
1、React 解析组件<MyCommponment/>
2、发现组件是类式定义,随后进行实例化,调用里面上的render,返回虚拟的DOM
3、虚拟的DOM转为真实的DOM,随后呈现在页面中
*/
</script>
</body>
</html>