文章目录

  • 前言:
  • 一,组件的基本理解和使用
    • 1. 函数组件
    • 2. 类式组件
    • 3.组件的注意事项
  • 二,组件的三大核心属性
    • 1.state
    • 2.props
    • 3.ref
  • 总结

前言:

  • React组件中默认封装了很多属性,有的是提供给开发者操作的,其中有三个属性非常重要:state、props、refs。通过这三大核心属性的使用,我们能够实现对组件的状态进行更新。

一,组件的基本理解和使用

1. 函数组件

 <script type="text/babel">function MyComponent() {return <h2>我是函数定义的组件(适用于简单组件的定义)</h2>}ReactDOM.render(<MyComponent />, document.getElementById('test'))</script>

函数组件的渲染过程

 1.React解析了组件标签,找到了对应的组件 2.发现这个组件是一个函数定义的,随后调用该函数,生成一个虚拟dom 3.最后将虚拟dom转化成为真实dom,呈现在页面中

2. 类式组件

<script type="text/babel">class MyComponent extends React.Component {render() {return <h2>我是类定义的组件适用于复杂数据类型</h2>}}ReactDOM.render(<MyComponent />, document.getElementById('test'))</script>

类式组件的渲染过程

1.React解析了组件标签,找到了对应的组件2.发现这个组件是一个类定义的,随后new出来一个实例对象,并通过该实例调用原型上的render方法3.将render()返回的内容生成一个虚拟dom4.最后将虚拟dom转化成为真实dom,呈现在页面中

3.组件的注意事项

组件名必须首字母大写虚拟DOM元素只能有一个根元素虚拟DOM元素必须有结束标签

二,组件的三大核心属性

1.state

  • state 是一个对象,它包含组件的数据状态,当状态变化时,会触发视图的更新。你可以理解它的作用跟 Vue 中的 data 对象类似。
<script type="text/babel">class Weather extends React.Component {constructor() {super()this.state = {isHot: false,wind: '微风'}this.chang = this.chang.bind(this)}render() {let { isHot, wind } = this.statereturn <h2 onClick={this.chang}>今天的天气很 {isHot ? "炎热" : "凉爽"},{wind}</h2>}hang() {console.log(this)this.setState({isHot: !this.state.isHot})}}ReactDOM.render(<Weather />, document.getElementById('test'))</script>

1. 注意事项

1.组件中render方法中的this为组件实例对象2.组件自定义的方法中this为undefined,如何解决?1.强制绑定this: 通过函数对象的bind()2.箭头函数3.状态数据,不能直接修改或更

2.简写方式

<script type="text/babel">class Weather extends React.Component { state = {isHot: false,wind: '微风'}render() {let { isHot, wind } = this.statereturn <h2 onClick={this.chang}>今天的天气很 {isHot ? "炎热" : "凉爽"},{wind}</h2>}chang = ()=>{this.setState({isHot: !this.state.isHot//这里的修改是一种合并,对比属性的变化,如果有赋新值,没有则跳过})}}ReactDOM.render(<Weather />, document.getElementById('test'))let a = new Weather()</script>

设置状态:setState

setState(object nextState[, function callback])

不能在组件内部通过 this.state 修改状态,因为该状态会在调用 setState() 后被替换。

setState() 并不会立即改变 this.state,而是创建一个即将处理的 statesetState() 并不一定是同步的,为了提升性能 React 会批量执行 stateDOM 渲染。

setState() 总是会触发一次组件重绘,除非在 shouldComponentUpdate() 中实现了一些条件渲染逻辑。


2.props

  • React 中组件通过 props 属性接收外部传入的数据,这点 Vue 跟 React 是一致的
  • react 中说的单向数据流值说的就是 props,根据这一特点它还有一个作用:组件之间的通信
  • props 本身是不可变的,但是有一种情形它貌似可变,即是将父组件的 state作为子组件的 props,当父组件的 state 改变,子组件的 props 也跟着改变,其实它仍旧遵循了这一定律:props 是不可更改的
<script type="text/babel">class MyComponent extends React.Component {render() {return (<ul><li>{this.props.name}</li><li>{this.props.age}</li></ul>);}}ReactDOM.render(<MyComponent name="Bob" age="18" />,document.getElementById("test"));</script>

props的特点:

  1. 每个组件对象都会有props(properties的简写)属性
  2. 组件标签的所有属性都保存在props中
  3. 内部读取某个属性值:this.props.propertyName
  4. 作用:通过标签属性从组件外 向组件内传递数据(只读 read only)
  5. 对props中的属性值进行类型限制和必要性限制

对props进行限制

  1. 引入 prop-type 库,这就是专门用于限制 props 属性的一个库
  2. 导入 prop-type 库,到当前页面
  3. 根据 Person.propTypes = {} 进行限制
class MyComponent extends React.Component {render() {return (<ul><li>{this.props.name}</li><li>{this.props.age}</li></ul>);}}// 校验类型MyComponent.propTypes = {name: PropTypes.string, // 这里的 PropTypes 变量是全局挂载的age: PropTypes.number,};ReactDOM.render(<MyComponent name="Bob" age={18} />,document.getElementById("test"));

props的简写

<script type="text/babel">class Weather extends React.Component {constructor(props) {//是否接受,取决于是否使用外部数据super(props)//只能上面接受了props,super()就去传递,否则后续的使用,可能就会出现问题}static propTypes = {name: PropTypes.string.isRequired,//限制name为字符串类型,必填// age: PropTypes.number,sex: PropTypes.string,speak: PropTypes.func}static defaultProps = {sex: '男',}render() {let { name, age, sex } = this.propsreturn (<ul><li>姓名:{name}</li><li>性别:{sex}</li><li>年龄:{age + 1}</li></ul>)}} ReactDOM.render(<Weather name="tom" age={26} sex="女" />, document.getElementById('test'))</script>

函数组件使用props

<script type="text/babel">// 函数组件function MyComponent(props) {return (<ul><li>{props.name}</li><li>{props.age}</li></ul>);}// 校验类型MyComponent.propTypes = {name: PropTypes.string,age: PropTypes.number,};ReactDOM.render(<MyComponent name="Bob" age={18} />,document.getElementById("test"));</script>

3.ref

  • React 中的 Refs 可以让我们访问 DOM 节点,它有三种使用方式:字符串方式回调函数式createRef
  • 在 React 中 Refs 提供了一种方式,允许用户访问DOM 节点或者在render方法中创建的React元素
  • 在 React单项数据流中,props是父子组件交互的唯一方式。要修改一个子组件,需要通过的新的props来重新渲染。
    但是在某些情况下,需要在数据流之外强制修改子组件。被修改的子组件可能是一个React组件实例,也可能是一个DOM元素。对于这两种情况,React 都通过 Refs的使用提供了具体的解决方案。

字符串方式

<script type="text/babel">class MyComponent extends React.Component {handleAlert = () => {// 在 refs 中获取定义的 ref 标识const { myInput } = this.refs;console.log(myInput); // alert(myInput.value);};render() {return (<div>{/* 使用 ref="" 方式直接定义字符串标识*/}<input ref="myInput" type="text" /><button onClick={this.handleAlert}>alert</button></div>);}}ReactDOM.render(<MyComponent />, document.getElementById("test"));</script>

回调函数方式

<script type="text/babel">class MyComponent extends React.Component {handleAlert = () => {// 直接从组件实例上获取 myInputconsole.log(this.myInput); // alert(this.myInput.value);};render() {return (<div>{/* ref 直接定义成一个回调函数,参数就是节点本身,将它赋值给组件的一个 myInput 属性 */}<input ref={(ele) => (this.myInput = ele)} type="text" /><button onClick={this.handleAlert}>alert</button></div>);}}ReactDOM.render(<MyComponent />, document.getElementById("test"));</script>

React官方提示:

如果 ref 回调函数是以内联函数的方式定义的,在更新过程中它会被执行两次,第一次传入参数 null,然后第二次会传入参数 DOM 元素。这是因为在每次渲染时会创建一个新的函数实例,所以 React 清空旧的 ref 并且设置新的。通过将 ref 的回调函数定义成 class 的绑定函数的方式可以避免上述问题,但是大多数情况下它是无关紧要的。


createRef -官方推荐使用

<script type="text/babel">class MyComponent extends React.Component {// 创建 refmyInput = React.createRef();handleAlert = () => {console.log(this.myInput.current); // 这里需要注意,元素是在 current 属性上alert(this.myInput.current.value);};render() {return (<div>{/* 将创建好的 ref 附加到元素上 */}<input ref={this.myInput} type="text" /><button onClick={this.handleAlert}>alert</button></div>);}}ReactDOM.render(<MyComponent />, document.getElementById("test"));</script>

上面就是使用 React.createRef() 方法创建 ref 的方式,特别需要注意的是,创建出来的 ref 的值是一个对象,我们需要的 DOM 元素是放在对象的 current 属性上,如上面的 this.myInput.current。

总结

以上就是React面向组件编程中的一部分。希望本篇文章能够帮助到你,若有错误欢迎指出,不懂得可以评论区或者私信问我,我也会一 一解答。谢谢观看!
我的其他文章:https://blog.csdn.net/m0_60970928?type=blog