react的组件

组件

组件是用来实现局部功能的代码和资源的集合(html/css/js),用来复用代码。

react中分为函数式组件和类式组件。函数式组件就是一个函数,函数的返回值就是组件的视图内容。类式组件就是通过class关键字创建的类,类式组件通过render函数返回视图内容。

函数式组件

jsx 复制代码
function Good(){
    return <div>
        <h1>news</h1>
    </div>
}

类式组件

类式组件必须继承React.Component

jsx 复制代码
class Good extends React.Component{
    
}
  1. React解析组件标签,找到Good组件
  2. 发现组件是使用类定义的,随后new出来该类的实例,并通过该类实例调用到原型上的render()
  3. 将render返回的虚拟DOM转为真实DOM,随后呈现在页面中

简单组件和复杂组件

如果一个组件有状态就是复杂组件,如果一个组件没有状态就是简单组件。

组件实例的属性

组件实例属性包含state、props、refs这三个常用的属性。其中refs只能在类组件中使用,如果在函数式组件中想要使用refs需要使用其他的api获取元素引用。

state

state是组件对象最重要的属性,值是对象。组件被称为状态机,通过更新组件的state来更新对应的页面显示。

状态必须通过setState修改,setState()接收一个对象,对象中设置需要更改的key和value。

jsx 复制代码
class Demo extends React.Component{
	state = {
		description:'hello'
	}
	handleClick(){
		this.setState({
			descriptin:'hello'
		});	
	}
	render(){
		return <div>
			<span>{this.state.description}</span>
			<button onClick={this.handleClick}>change</button>
		</div>
	}
}

props

组件实例属性props指的是从外部传递给组件的值,props在组件内部是只读的,不能通过this.props.xxx修改。

jsx 复制代码
class Person extends React.Component{
    render(){
        const {
            name,
            age,
            sex
        } = this.props;
        return <>
        	<ul>
            	<li>{name}</li>
            	<li>{age}</li>
            	<li>{sex}</li>
        	</ul>
        </>
    }
}

我们可以通过propsTypes限制props的类型,通过defaultProps设置props的默认值。propsTypes和defaultProps都是类的静态成员,除了直接使用Person设置之外还可以通过类的语句块中通过static关键字设置。

jsx 复制代码
// 限制props的类型
Person.propTypes = {
    name:PropTypes.string,
    age:PropTypes.number,
    sex:PropTypes.string
}
// 设置props的默认值
Person.defaultProps = {
    name:'hello'
}
// 向组件传递props
React.render(<Person name="Tom" age={18} sex="Man" />,document.getElementById('app'));
let p = {
    name:"Tom", 
    age:18, 
    sex:"Man" 
}
React.render(<Person {...p}/>,document.getElementById('test'));

static关键字设置propsTypes

jsx 复制代码
class Person extends React.Component{
	static propsTypes = {
		name:PropTypes.string,
    	age:PropTypes.number,
   	 	sex:PropTypes.string
	}
	static defaultProps = {
		name:'hello'
	}
	render(){
		return <div>
			// ...
		</div>
	}
}

refs

组件实例属性refs,refs指的是获取元素的引用。通过给元素设置ref属性得到其引用。refs从使用方式上分为字符串类型、函数类型。字符串类型的如下所示:

jsx 复制代码
class Person extends React.Component{
    render(){
        return <>
         	<input ref="input_left" type="text" placeholder="点击按钮提示数据" />
        	<button onClick={this.tooltip}>点击提示数据</button>
        	<input ref="input_right" type="text" placeholder="失焦提示数据" />
        </>
    }
}
回调函数形式的refs

回调形式的ref在更新时会执行两次,第一次会传递一个null,第二次才会传递元素。这是因为在更新时会实例化一个新的对象,并重新渲染。

回调函数分为内联的回调函数和类绑定的回调函数

jsx 复制代码
 class Person extends React.Component {
    state = {
    }
    static propTypes = {
      name: PropTypes.string,
      age: PropTypes.number,
      gender: PropTypes.string
    }
    static defaultProps = {
      name: 'hello'
    }
    constructor(props) {
      super(props);
    }
    tooltip = (e)=>{
      alert(this.input_left.value)
    }
    toolTipRight = () => {
      alert(this.input_right.value)
    }
    render() {
      return <div>
        <input ref={(el) => {this.input_left = el;}} type="text" 			placeholder="点击按钮提示数据" />
        <button onClick={this.tooltip}>点击提示数据</button>
        <input ref={(el) => {this.input_right = el;}} onBlur=			{this.toolTipRight} type="text" placeholder="失焦提示数据" />
      </div>
    }
  }
createRef的refs

除了上面的方式之外,还可以通过createRef创建容器,然后获取元素的引用。

jsx 复制代码
class Person extends React.Component {
    myRef = React.createRef()
    myRef2 = React.createRef()
    state = {
    }
    constructor(props) {
      super(props);
    }
    tooltip = (e)=>{
      console.log(this.myRef)
      alert(this.myRef.current.value);
    }
    toolTipRight = () => {
      alert(this.myRef2.current.value);
    }
    render() {
      return <div>
        <input ref={this.myRef} type="text" placeholder="点击按钮提示数据" />
        <button onClick={this.tooltip}>点击提示数据</button>
        <input ref={this.myRef2} onBlur={this.toolTipRight} type="text" placeholder="失焦提示数据" />
      </div>
    }
  }

事件处理

通过onXxx属性指定事件处理函数。

  • React使用的是自定义事件,不是原生事件。为了更好的兼容性
  • React中的事件是通过委托方式处理的。为了高效

通过event.target得到发生的事件的DOM元素对象

受控组件

页面中所有输入类的DOM,随着输入把数据存入state就是受控组件。

jsx 复制代码
 class Login extends React.Component {
    state = {
      userName:'',
      password:''
    }
    submit=(e)=>{
      e.preventDefault();
      const {userName,password} = this.state;
    }

    saveFormData = (key) => {
      return (e) => {
        this.setState({
          [key]: e.target.value
        });
      }
    }
  

    render() {
      return <form action="" onSubmit={this.submit}>
        用户名<input ref={(el) => this.userNameInput = el} onChange={this.saveFormData('userName')} type="text" name="username" />
        密码<input ref={(el) => this.passwordInput = el} onChange={this.saveFormData('password')} type="password" name="password" /> 
        <button>登录</button>
      </form>
    }
  }
相关推荐
木易 士心几秒前
JavaScript 闭包原理和实践深度解析
开发语言·javascript·ecmascript
小羊没烦恼!1 分钟前
系统内部模块(子系统)之间的耦合以及模块(子系统)划分
java·开发语言·前端·数据库·算法·c#
ITOM运维行者30 分钟前
PHP性能监控怎么做?从响应时间到慢函数的6个关键指标
前端·javascript·后端
成旭先生42 分钟前
AI 文本审核 API:一段中文文本判风险等级、命中标签与处置建议
java·前端·人工智能·api接口·内容风控·文本审核·ugc审核
liangshanbo12151 小时前
前端面试题:AI 对话中超长消息导致内存溢出,怎么解决?
java·开发语言·前端
静默回滚1 小时前
PDF能打开却不能复制,原来是权限密码
前端
律宏阔1 小时前
Dart FFI 内存管理:用 using + Arena 替代嵌套 try-finally
前端·flutter
guslegend1 小时前
脚手架入门:必要性、核心功能与执行原理
前端·架构·node.js·脚手架·前端工程化
律宏阔1 小时前
Flutter 调用 Go:从 c-shared + ffigen 到 @Native + Native Assets 踩坑记录
前端·flutter
LEE1 小时前
前端转型全栈 05:SQL 与迁移,AI 写的 SQL 怎么安全上线
前端·后端·ai编程