目录
state
state是组件对象最重要的属性,值是对象(可以包含多个 key-value的组合);组件被称为“状态机”,通过更新组件来对应页面显示(重新渲染组件),也就是有状态组件:
事件绑定
在React中进行事件绑定来渲染数据通过使用以下方式进行:
<body>
<div id="root"></div>
<!-- 引入react核心库 -->
<script src="./node_modules/react/umd/react.development.js"></script>
<!-- 引入react-dom,用于支持react操作dom -->
<script src="./node_modules/react-dom/umd/react-dom.development.js"></script>
<!-- 引入babel,用于将jsx转为js -->
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
// 创建组件
class Weather extends React.Component {
constructor(props){
super(props)
this.state = {isHot:true,wind:'微风'}
// 将changeWeather的this指向Weather的实例对象上
this.changeWeather = this.changeWeather.bind(this)
}
render(){
// 读取状态
const {isHot,wind} = this.state
return (
<div>
<h1>今天天气很{isHot ? '炎热' : '寒冷'},{wind}</h1>
<button onClick={this.changeWeather}>点击切换天气</button>
</div>
)
}
changeWeather(){
// 获取原来的isHot的值
const isHot = this.state.isHot
// 注意:状态必须通过 setState 进行更新,且更新是一种合并不是替换
this.setState({isHot:!isHot})
// 禁止直接对state状态进行修改
// this.state.isHot = !isHot 这种写法是错误的
}
}
// 渲染页面到组件
ReactDOM.render(<Weather/>,document.getElementById('root'))
</script>
</body>
虽然能实现效果,但是未免有些过于繁琐,要知道我们在创建类的时候,如果不是通过new出来的实例传入的数据,我们完全可以把固定的数据写在构造器的外面,如下:
<script>
class person {
constructor(name,age){
this.name = name
this.age = age
}
// 类里面可以直接写赋值语句
gender = '男'
}
const p1 = new person('张三',18)
console.log(p1)
</script>
所以我们也可以将state状态写在构造器外面,构造器可以直接省略,通过箭头函数的this指向外层的this来达到修改state中this数据的目的:
<script type="text/babel">
// 创建组件
class Weather extends React.Component {
// 初始化状态
state = {isHot:true,wind:'微风'}
render(){
// 读取状态
const {isHot,wind} = this.state
return (
<div>
<h1>今天天气很{isHot ? '炎热' : '寒冷'},{wind}</h1>
<button onClick={this.changeWeather}>点击切换天气</button>
</div>
)
}
// 自定义方法---要用赋值语句的形式+箭头函数
changeWeather = ()=> {
const isHot = this.state.isHot
this.setState({isHot:!isHot})
}
}
// 渲染页面到组件
ReactDOM.render(<Weather/>,document.getElementById('root'))
</script>
注意:
1)组件中render方法中的this为组件实例对象。
2)组件自定义的方法中this为undefined,强制绑定this可以通过函数对象的bind()或箭头函数。
3)状态数据,不能直接修改或更新。
props
每个组件对象都会有 props 属性,组件标签的所有属性都保存在 props 中。其基本使用如下:
<script type="text/babel">
// 创建组件
class Person extends React.Component {
render(){
const {name,age,gender} = this.props
return (
<ul>
<li>姓名: {name}</li>
<li>年龄: {age}</li>
<li>性别: {gender}</li>
</ul>
)
}
}
// 渲染页面到组件
ReactDOM.render(<Person name="张三" age="18" gender="男" />,document.getElementById('root'))
</script>
如果想批量传递props,可以通过以下方式:
构造器是否接受props,是否传递给super,取决于:是否希望在构造器中通过this访问props。
函数式组件使用props
<script type="text/babel">
// 函数式组件使用props
function Person(props){
const {name,age,gender} = props
return (
<ul>
<li>姓名: {name}</li>
<li>年龄: {age}</li>
<li>性别: {gender}</li>
</ul>
)
}
// 渲染页面到组件
ReactDOM.render(<Person name="张三" age="18" gender="男"/>,document.getElementById('root'))
</script>
注意:
1)通过标签属性从组件外向组件内传递变化的数据
2)props是只读的,组件内部不要修改props
refs
组件内的标签可以定义ref属性来标识自己
字符串形式的ref
<script type="text/babel">
// 创建组件
class Demo extends React.Component {
// 展示输入框左侧的数据
showData = ()=>{
const {input1} = this.refs
alert(input1.value)
}
// 展示输入框右侧的数据
showData2 = ()=>{
const {input2} = this.refs
alert(input2.value)
}
render(){
return (
<div>
<input ref="input1" type="text" placeholder="点击按钮显示数据" />
<button onClick={this.showData}>点我显示数据</button>
<input ref="input2" onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
</div>
)
}
}
// 渲染组件
ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>
虽然这种方式很简单,但是存在一定的效率问题,官方文档明确说明不建议去使用它:
回调形式的ref
拿到当前ref所在的节点,react帮助我们调用函数然后传进来,之后挂载到实例自身上。
<script type="text/babel">
// 创建组件
class Demo extends React.Component {
// 展示输入框左侧的数据
showData = ()=>{
const {input1} = this
alert(input1.value)
}
// 展示输入框右侧的数据
showData2 = ()=>{
const {input2} = this
alert(input2.value)
}
render(){
return (
<div>
<input ref={c => this.input1 = c} type="text" placeholder="点击按钮显示数据" />
<button onClick={this.showData}>点我显示数据</button>
<input ref={c => this.input2 = c} onBlur={this.showData2} type="text" placeholder="失去焦点提示数据" />
</div>
)
}
}
// 渲染组件
ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>
使用回调形式的ref会出现以下问题,如果想解决这个问题,可以用以下方式:
<script type="text/babel">
// 创建组件
class Demo extends React.Component {
// 展示输入框的数据
showData = ()=>{
const {input1} = this
alert(input1.value)
}
saveInput = (c)=>{
this.input1 = c
console.log('@');
}
render(){
return (
<div>
{/*在JSX语法中,注释的书写方式是外层包裹大括号,表明里面是JS语法,写上注释即可表明当前为注释*/}
<input ref={this.saveInput} type="text" placeholder="点击按钮显示数据" />
<button onClick={this.showData}>点我显示数据</button>
</div>
)
}
}
// 渲染组件
ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>
createRef的使用
React.createRef调用后可以返回一个容器,该容器可以存储被ref所标识的节点。但这种形式有一种缺点就是只能容纳一个元素进行使用,如果想出里多个元素需创建多个createRef容器。
<script type="text/babel">
// 创建组件
class Demo extends React.Component {
// 创建容器
myRef = React.createRef()
myRef1 = React.createRef()
// 展示输入框的数据
showData = ()=>{
console.log(this.myRef.current);
alert(this.myRef.current.value)
}
showData1 = ()=>{
console.log(this.myRef1.current);
}
render(){
return (
<div>
{/*在JSX语法中,注释的书写方式是外层包裹大括号,表明里面是JS语法,写上注释即可表明当前为注释*/}
<input ref={this.myRef} type="text" placeholder="点击按钮显示数据" />
<button onClick={this.showData}>点我显示数据</button>
<input type="text" onBlur={this.showData1} ref={this.myRef1} placeholder="另一个input" />
</div>
)
}
}
// 渲染组件
ReactDOM.render(<Demo/>,document.getElementById('root'))
</script>
表单处理
在React中表单处理有以下两种形式:
受控组件
受控组件是指其值受到React控制的表单元素,React中可变状态通常保存到state中,并且只能通过setState()方法进行修改。React将state与表单元素值value绑定到一起,由state的值来控制表单元素的值。案例如下:
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
// 在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
state = {
input:'',
txt:'',
city:'sh',
isChecked:true
}
// 将表单元素的值设置为state的值(控制表单元素值的变化
// 处理输入框的变化
handleInput = (e) =>{
this.setState({
input:e.target.value
})
}
// 处理文本框的变化
handleTxt = (e) =>{
this.setState({
txt:e.target.value
})
}
// 处理下拉框的变化
handleSelect = (e) =>{
this.setState({
city:e.target.value
})
}
// 处理复选框的变化
handleCheck = (e) =>{
this.setState({
isChecked:e.target.checked
})
}
render() {
return (
<div>
{/* 给表单元素绑定change事件 */}
{/* 输入框 */}
<input type="text" value={this.state.input} onChange={this.handleInput} />
<br />
{/* 文本框 */}
<textarea value={this.state.txt} onChange={this.handleTxt}></textarea>
<br />
{/* 下拉框 */}
<select value={this.state.city} onChange={this.handleSelect}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="tj">天津</option>
</select>
<br />
{/* 复选框 */}
<input type="checkbox" checked={this.state.isChecked} onChange={this.handleCheck} />
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
多表单元素优化:可以看到上文每个表单元素都要有一个单独的事件处理程序,十分的繁琐,能不能用一个事件处理程序处理多个表单元素呢?答案是可以的,如下:
1)给表单元素添加name属性,名称与state相同
2)根据表单元素类型获取对应值
3)在change事件处理程序中通过 [name] 来修改对应的state
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
// 在state中添加一个状态,作为表单元素的value值(控制表单元素值的来源)
state = {
input:'',
txt:'',
city:'sh',
isChecked:true
}
// 将表单元素的值设置为state的值(控制表单元素值的变化
handleForm = (e) =>{
// 获取当前DOM元素的target
const target = e.target
// 根据类型获取值
const value = target.type === 'checkbox'
? target.checked
: target.value
// 获取 name
const name = target.name
this.setState({
[name]: value
})
}
render() {
return (
<div>
{/* 给表单元素绑定change事件 */}
{/* 输入框 */}
<input type="text" name="input" value={this.state.input} onChange={this.handleForm} />
<br />
{/* 文本框 */}
<textarea name="txt" value={this.state.txt} onChange={this.handleForm}></textarea>
<br />
{/* 下拉框 */}
<select name="city" value={this.state.city} onChange={this.handleForm}>
<option value="sh">上海</option>
<option value="bj">北京</option>
<option value="tj">天津</option>
</select>
<br />
{/* 复选框 */}
<input name='isChecked' type="checkbox" checked={this.state.isChecked} onChange={this.handleForm} />
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
非受控组件
借助于ref(作用:获取DOM或组件),使用原生DOM方式来获取表单元素值。现用现取
import React from 'react';
import ReactDOM from 'react-dom';
class App extends React.Component {
constructor(){
super()
// 1.调用React.createRef()方法创建一个ref 对象
this.txtRef = React.createRef()
}
getTxt = () =>{
// 3.通过ref 对象获取到文本框的值
console.log('文本框的值:',this.txtRef.current.value)
}
render() {
return (
<div>
{/* ⒉将创建好的ref 对象添加到文本框中 */}
<input type="text" ref={this.txtRef} />
<button onClick={this.getTxt}>打印文本框的值</button>
</div>
)
}
}
ReactDOM.render(<App />,document.getElementById('root'))
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/139997.html