二,组件

1,组件有两种定义方式:class(类组件)和使用函数(函数组件)

class:

  • 继承自React.Component
  • 内部必须定义render方法,返回该组件UI的React元素

使用函数:

  接收props作为参数,返回代表这个组件UI的React元素结构,

  例如:

function Welcome(props) {
        return <h1>hello,{props.name}</h1>;
}

 

2,props和state

例如做一个展示用户的列表,通过点击按钮给用户点赞:

props:

  用于把父组件中的数据或方法传递给子组件。props是只读的,不能在组件内部修改props。

在父组件中引用子组件User:<User name='sxww' age='26' /> ,此时User的props为props={name: 'sxww',age: '26'},User中使用props:

import React, { Component } from "react";
class User extends Component {
    constructor(props){
        super(props);//实际上调用了React.Component这个class的constructor方法,用来完成React组件的初始化工作
    }
    render() {
        const props = this.props;
        return (
            <div>
         <div><label>姓名:</label><span>props?.name</span></div>
         <div><label>年龄:</label><span>props?.age</span></div>
            </div>
        )
    }
}
export default User;   

state:

  组件的state是组件内部的状态,在constructor中通过this.state定义组件的初始状态,通过调用this.setState方法改变组件状态。

import React, { Component } from "react";
class User extends Component {
    constructor(props) {
        super(props);
        this.state = { count: 0 }
    }
    handleClick() { let count = this.state.count; count++; this.setState({ count: count }) }
    render() {
        const props = this.props;
        return (
            <div>
                <button onClick={() => { this.handleClick(); }}></button>
                <span>{this.state.count}</span>
            </div>
        )
    }
}
export default User;

react组件可以看做是一个函数,函数的输入是props和state,输出是组件的UI

UI = Component(props,state)

3,有状态组件和无状态组件

如果一个组件内部状态是不变的,则不用state,这样的组件称为无状态组件

一个组件内部状态会发生变化,则需要使用state,这样的组件称为有状态组件

定义无状态组件应该尽量将其定义为无状态组件。无状态组件不要关心状态的变化,只聚焦于UI的展示。这样,上述代码中获取用户信息,姓名、年龄、点赞数都放在父组件(有状态组件),handleClick也放到父组件,User只展示用户信息。

React应用组件设计的一般思路是,通过定义少数的有状态组件管理整个应用的状态变化,并且将状态通过props传递给其余的无状态组件,由无状态组件完成页面绝大部分UI的渲染工作。总之,有状态组件主要关注处理状态变化的业务逻辑,无状态组件主要关注组件UI的渲染。

4,属性校验和默认属性

 

 

 组件内部声明props应该暴露出那些接口,React提供了ProTypes这个对象,用于校验组件属性的类型

import PropTypes from 'prop-types';
class User extends React.Component{
    
}
User.propTypes = {
 info:PropTypes.object,
handleClick:PropTypes.func }

当使用PropTypes.object或PropTypes.array校验属性时,无法校验对象的结构和数组元素的类型,这种情况下,我们可以使用PropTypes.shape或PropTypes.arrayOf。如果属性是组件的必须属性,则需要在PropTypes的类型属性上调用isRequired。

User.propTypes = {
 info:PropTypes.shape({
  name: PropTypes.string,
age: PropTypes.number
}).isRequired, handleClick:PropTypes.func.isRequired,
photos: PropTypes.arrayOf(PropTypes.string),
}

React还提供了为组件属性指定默认值的特性,这个特性通过defaultProps实现,当组件属性未被赋值,组件会使用defaultProps的默认属性:

User.defaultProps = {
 info:{
  name:
'sxww', age: 26 } }

5,组件样式

为组件添加样式的方法有两种:外部CSS样式表和内联样式。

外部CSS样式表:和平时开发web应用时使用外部css文件相同,唯一区别在react元素使用className来代替class作为选择器。

function Welcome(props) {
        return <h1 className="foo">hello,{props.name}</h1>;
}
//css样式表
.foo{...}

class名称冲突的解决方案:可以使用CSS Modules,CSS Modules会对样式文件中的class名称重新命名从而保证其唯一性。(https://github.com/css-modules/css-modules)

内联样式:css in js,样式的属性名必须使用驼峰命名法。

function Welcome(props) {
        return <h1 style={{height:'50px',fontSize:'14px'}}>hello,{props.name}</h1>;
}

6,组件和元素

React组件是由若干React元素组建而成的。一个React组件是一个class或函数,接收一些属性作为输入,返回一个React元素。

 

posted on 2022-10-19 10:52  Zoie_ting  阅读(57)  评论(0编辑  收藏  举报