2019-09-26 16:55:50 u011013840 阅读数 164
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57505 人正在学习 去看看 李宁

react组件切换

2018-09-21 20:22:56 LXY224 阅读数 454
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57505 人正在学习 去看看 李宁

一、组件的几种创建方式

对于React来说组件Component算是它的核心之一。用了React的时间也不短了,记录一下以便以后翻看

1 createClass

用ES5的方法React.createClass来创建一个组件

import React from 'react';
class Test = React.createClass({
    render(){
        return(
        <div></div>
        )
    }
}) 
export default Test;

2​ 采用React.createClass的方法来创建组件

import React from 'react';

class Test extends React.Component {
    constructor(props) {
        super(props);
        }
        render() {
            return (
            <div></div>
        );
    }
}

export default Test;

ES6对类和继承有语法级别的支持,所以使用ES6来创建组件,看起来更加的优雅简单。在继承之后,通过super来调用父类的构造函数。同时组件的state是在this.state中进行赋值。对于组件来说,组件的props属性是父组件传递给子组件的,子组件内部不应该对props进行修改。state是组件内部自己维护的一种状态,组件可以通过setState来更新自己的状态。

3 无状态组件

和以上的组件创建方式不同还有一种叫做无状态组件。FB把它称为Stateless Function Componnet。在什么时候我们考虑使用这样的组件呢?当我们的组件只需要做一些展示而不需要去维护任何状态时候,无状态组件更加指的推荐。这种组件不需要关系

 

 

在antd form使用的过程中遇到了一个关于初始值(initialValue)的初始化和再更新的问题,究其原因原来是React的受控组件和非受控组件“捣鬼”。

官方文档永远是最好的学习材料:

https://reactjs.org/docs/forms.html#controlled-components
https://reactjs.org/docs/uncontrolled-components.html

https://goshakkk.name/controlled-vs-uncontrolled-inputs-react/

受控组件

HTML表单元素与React中的其他DOM元素有所不同,因为表单元素天生就保留着一下内部状态。当用户提交表单时,HTML的默认行为会使这个表单跳转到一个新页面。在React中也是这样的。通常我们都会构造一个处理提交表单并可访问用户输入表单数据的函数,实现这一点的标准方法就是使用“受控组件”技术。

受控组件从形式上来说就是为表单组件添加value属性,表现如下,在这种情况下,你的任何输入都不能在去改变input的值。

<input type="text" value="hello world"/>

在HTML中,想input、textarea这类的表单元素都会为维持一个自身状态并且根据用户输入来进行更新,但是在React中可变的状态通常保存在组件的状态属性中并且通过setState方法来进行更新。在React中负责渲染表单的组件仍然控制用户后续输入时所需的变化。相应的,其值由React控制的输入表单元素称为“受控组件”。如下代码所示

class NameForm extends React.Component {
  constructor(props) {
    super(props);
    this.state = {value: ''}
  }

  handleChange=(event)=>{
    this.setState({value: event.target.value});
  }

  handleSubmit=(event)=>{
    event.preventDefault();
  }
//value的值由this.state.value进行设置,每次触发change时候,我们都会去动态的更新state
  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" value={this.state.value} onChange={this.handleChange} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

使用“受控组件”每个状态都需要有一个与之相关的处理函数。

很明显,受控组件的缺点在于:需要为数据可能变化的每一种方法都需要编写一个事件处理函数

非受控组件

从形式上来说就是没有为表单组件添加value属性,你的任何输入都是由input组件自身控制。非受控组件真是数据保存在DOM中,所以使用非受控组件可以更容易的集成

对于React的实现来说,如果需要编写一个非受控组件,而非为每个状态更新编写事件处理函数,我们可以使用ref从dom中来获取该组件的值:

class NameForm extends React.Component {
  constructor(props) {
    super(props);
  }

  handleSubmit=(event)=>{
    alert('A name was submitted: ' + this.input.value);
    event.preventDefault();
  }

  render() {
    return (
      <form onSubmit={this.handleSubmit}>
        <label>
          Name:
          <input type="text" ref={(input) => this.input = input} />
        </label>
        <input type="submit" value="Submit" />
      </form>
    );
  }
}

对于非受控组件,你可以通过ref来获取它的值,这样的写法看起不是那么“React”。它也能够更加容易的和其他非React的代码进行耦合。缺点在于没有办法进行表单的校验等。

简单来说,其实就是你能不能够控制组件的值,可控组件的value是通过state的来做的赋值,所以你可以通过setState来动态的改变它的值。对于不可控组件,它的value是元素自身属性带有的,那么你是不能去操作而只能获取的,那它就是你不能够控制的。

简单来说,如果想要一个form变成可控的,那么你需要做的通过state/props来set它的值

在以下场景中推荐使用可控组件:

1 需要feedback,例如验证

2 提交按钮不可用除非所有表单数据都是合法数据

3 迫使用户输入一个符合规范的数据,例如信用卡或者电话

2019-10-16 12:29:08 m0_37686205 阅读数 17
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57505 人正在学习 去看看 李宁

React创建组件

React创建组件有两种方式:构造函数和class关键字

  1. 构造函数:
    第一种基本组件的创建方式(构造函数),就是一个最基本的组件,想要把组件放在页面中,可以把 构造函数的名称,当作 组件的名称,以HTML标签形式引入页面中即可

注意:React在解析所有的标签的时候,是以标签的首字母来区分的,如果标签的首字母是小写的,那么就按照 普通的 HTML 标签来解析,如果首字母是大写的,则按照 组件的形式去解析渲染,所以,组件的首字母必须大写

父组件向子组件传递数据

  • 属性扩散(使用方法为…Obj,把该对象的所有属性,放到这个位置,然后在组件中,必须 显式的在构造函数参数列表中,定义props属性来接收,最后在返回的JSX标签中以props.属性的方式展示出来)

注意:通过props得到的任何数据都是只读的,不能重新赋值

  • 将组件封装到单独的文件中(使用export default 组件名将创建的组件暴露出去 )
  1. class关键字

基于class关键字创建组件

  • 使用 class 关键字来创建组件(通过extends关键字,继承React.component这个类,如果想要引用这个组件,可以把类的名称,以标签的形式,导入到JSX中使用)
class Person extends React.Component{
    // 通过报错提示得知:在class创建的组件中,必须定义一个render函数
    render(){
        // 在render函数中,必须返回一个null或者符合规范的虚拟DOM元素
        return <div>
            <h1>这是用 class 关键字创建的组件!</h1>
        </div>;
    }
}

同样的,如果想要给组件添加一些属性(通过外界传递一些数据),首先也是在组件上(使用子组件的时候写明一些数据)写明属性,然后在组件的render中使用this.props.属性名获得相应的属性名称,并进行一些基本的处理。

注意:

  • class方式定义的组件自身就带有porps属性,可以直接通过this.props来获得外界传递过来的数据,但是在function定义的组件中,如果想要使用props,必须在组件中先定义,否则无法直接使用
  • 两种方式创建的组件(或者说只要是组件),组件的props,都是只读的

两种创建组件方式的对比

  1. 用构造函数创建出来的组件:专业的名字叫做“无状态组件”
  2. 用class关键字创建出来的组件:专业的名字叫做“有状态组件”

用构造函数创建出来的组件,和用class创建出来的组件,这两种不同的组件之间的本质区别就是:有无state属性!!!
有状态组件和无状态组件之间的本质区别就是:有无state属性!同时,class创建的组件,有自己的生命周期函数,但是function创建的组件,没有自己的生命周期函数;

问题:什么时候使用有状态组件,什么时候使用无状态组件

  1. 如果有一个组件需要存放自己的私有数据,或者需要在组件的不同阶段执行不同的业务逻辑,此时,非常适合使用class创建出来的组件
  2. 如果有一个组件,只需要根据外界传递过来的props,渲染固定的 页面结构即可,此时,非常适合使用function创建出来的无状态组件(使用无状态组件的一个好处是,由于剔除了组件的生命周期,所以,运行速度会相对快一些)
2019-07-11 21:43:36 ThisOnly 阅读数 69
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57505 人正在学习 去看看 李宁

基本使用:

// 从 react 的包当中引入了 React。只要你要写 React.js 组件就必须引入React, 因为react里有一种语法叫JSX,稍后会讲到JSX,要写JSX,就必须引入React
import React from 'react'
// ReactDOM 可以帮助我们把 React 组件渲染到页面上去,没有其它的作用了。它是从 react-dom 中引入的,而不是从 react 引入。
import ReactDOM from 'react-dom'

// ReactDOM里有一个render方法,功能就是把组件渲染并且构造 DOM 树,然后插入到页面上某个特定的元素上
ReactDOM.render(
// 这里就比较奇怪了,它并不是一个字符串,看起来像是纯 HTML 代码写在 JavaScript 代码里面。语法错误吗?这并不是合法的 JavaScript 代码, “在 JavaScript 写的标签的”语法叫 JSX- JavaScript XML。
  <h1>欢迎进入React的世界</h1>,
// 渲染到哪里
  document.getElementById('root')
)

元素与组件

如果代码多了之后,不可能一直在render方法里写,所以就需要把里面的代码提出来,定义一个变量,像这样:

import React from 'react'
import ReactDOM from 'react-dom'
// 这里感觉又不习惯了?这是在用JSX定义一下react元素
const app = '<h1>欢迎进入React的世界</h1>'
ReactDOM.render(
  app,
  document.getElementById('root')
)

函数式组件( 无状态组件 PureComponent)

由于元素没有办法传递参数,所以我们就需要把之前定义的变量改为一个方法,让这个方法去return一个元素:

import React from 'react'
import ReactDOM from 'react-dom'

// 特别注意这里的写法,如果要在JSX里写js表达式(只能是表达式,不能流程控制),就需要加 {},包括注释也是一样,并且可以多层嵌套
const app = (props) => <h1>欢迎进入{props.name}的世界</h1>

ReactDOM.render(
  app({
    name: 'react'
  }),
  document.getElementById('root')
)

这里我们定义的方法实际上也是react定义组件的第一种方式-定义函数式组件,这也是无状态组件。但是这种写法不符合react的jsx的风格,更好的方式是使用以下方式进行改造

//函数式组件的标准写法
import React from 'react'
import ReactDOM from 'react-dom'

const App = (props) => <h1>欢迎进入{props.name}的世界</h1>

ReactDOM.render(
  // React组件的调用方式
  <App name="react" />,
  document.getElementById('root')
)

这样一个完整的函数式组件就定义好了。但要注意!注意!注意!组件名必须大写,否则报错。

class组件

ES6的加入让JavaScript直接支持使用class来定义一个类,react的第二种创建组件的方式就是使用的类的继承,ES6 class是目前官方推荐的使用方式,它使用了ES6标准语法来构建,看以下代码:

import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
      // 注意这里得用this.props.name, 必须用this.props
      <h1>欢迎进入{this.props.name}的世界</h1>
  	)
  }
}
ReactDOM.render(
  <App name="react" />,
  document.getElementById('root')
)

运行结果和之前完全一样,因为JS里没有真正的class,这个class只是一个语法糖, 但二者的运行机制底层运行机制不一样。

  • 函数式组件是直接调用, 在前面的代码里已经有看到
  • es6 class组件其实就是一个构造器,每次使用组件都相当于在实例化组件,像这样:
import React from 'react'
import ReactDOM from 'react-dom'

class App extends React.Component {
  render () {
    return (
  		<h1>欢迎进入{this.props.name}的世界</h1>
  	)
  }
}

const app = new App({
  name: 'react'
}).render()

ReactDOM.render(
  app,
  document.getElementById('root')
)

更老的一种方法

在16以前的版本还支持这样创建组件, 但现在的项目基本上不用

React.createClass({
  render () {
    return (
      <div>{this.props.xxx}</div>
  	)
  }
})

组件的组合、嵌套

将一个组件渲染到某一个节点里的时候,会将这个节点里原有内容覆盖

组件嵌套的方式就是将子组件写入到父组件的模板中去,且react没有Vue中的内容分发机制(slot),所以我们在一个组件的模板中只能看到父子关系

// 从 react 的包当中引入了 React 和 React.js 的组件父类 Component
// 还引入了一个React.js里的一种特殊的组件 Fragment
import React, { Component, Fragment } from 'react'
import ReactDOM from 'react-dom'

class Title extends Component {
  render () {
    return (
      <h1>欢迎进入React的世界</h1>
  	)
  }
}
class Content extends Component {
  render () {
    return (
      <p>React.js是一个构建UI的库</p>
  	)
  }
}
/** 由于每个React组件只能有一个根节点,所以要渲染多个组件的时候,需要在最外层包一个容器,如果使用div, 会生成多余的一层dom
class App extends Component {
  render () {
    return (
    	<div>
    		<Title />
        <Content />
      </div>
  	)
  }
}
**/
// 如果不想生成多余的一层dom可以使用React提供的Fragment组件在最外层进行包裹
class App extends Component {
  render () {
    return (
      <Fragment>
      	<Title />
        <Content />
      </Fragment>
  	)
  }
}
ReactDOM.render(
  <App/>,
  document.getElementById('root')
)
2019-09-21 14:54:15 lemisi 阅读数 14
  • 完全征服React Native

    React Native是Facebook于2015年推出的跨平台开发工具,可用于开发Android和iOS App,并且同时具有混合开发的优点(热更新,跨平台)以及本地App的性能。 本课程采用新的ES6开发,主要内容包括ReactNative的基础知识,ReactNative的布局,组件,API,封装本地API和组件,发布ReactNative App,本地与ReactNative深度结合

    57505 人正在学习 去看看 李宁

创建组件的两种方法

  • 1、工厂函数:function方式创建
  • 2、ES6class方式创建
  • 3、es5的react。createClass({render(){return 虚拟DOM}})

注意:组件名字必须大写;

工厂函数,以函数来创建组件

// 创建组件的方式,组件首字母大写
 function Hello(props){
     console.log(props)
      //props只读
      //return null表示此组件啥都不渲染


     // 在组件中,必须返回一个合法的jsx虚拟dom元素
     return <div>
         hello组件,{props.name}
     </div>
 }
const dog={
    name:"大黄",
    age:12
}

// 向组件传值:在组件里传{...对象名},或者 name={对象名.属性}
ReactDOM.render(<div><Hello {...dog}/></div>,document.getElementById('app'))

es6:使用class创建组件

// 使用class方式定义组件,必须让组件继承React.Component
class Mycomponent extends React.Component{
    // 在class关键字创建的组件中如果,想用外界传递的值,直接用就可以了,this.props.name就可以了
    // 在组件内必须有render函数,渲染组件对应的虚拟DOM
    render(){
        // render函数中,必须返回合法的jsx的虚拟DOM
        // 在class组件内部,this表示当前组件的实例对象
        return <div>hello{this.props.name}</div>
    }
}

// 向组件传值:在组件里传{...对象名},或者 name={对象名.属性}
ReactDOM.render(<div><Mycomponent {...dog}/></div>,document.getElementById('app'))

class创建组件拥有私有数据

class MyComponent extends React.Component{
    constructor(){
        // 在子类中,this只能放在super之后,否则会报错;
        super();
        //类似于vue的data(){return{}}
        //this.state的数据都是可读可写
        this.state={
            msg:"hello-world"
        }
    }
}

总结

  • 1、无论是class创建,还是function创建,他们的props都是只读的,不能修改;
  • 2、使用class关键字创建的组件,有自己的私有数据this.state,叫有状态组件
  • 3、但是使用function创建的组件,只有props,没有自己的私有属性和生命周期,叫无状态组件
  • 4、最本质的区别,有无私有数据,有无声明周期
  • 5、无状态组件,运行状态组件比有状态组件运行效率高;

props、和state/data的数据区别

  • 1、props中的数据都是外界传递过来的,只读不可重新赋值
  • 2、state/data都是组件私有的,可以重新赋值

React组件样式

阅读数 147

理解React的组件

阅读数 184

react父子组件通信

阅读数 6953

react组件分类

阅读数 185

没有更多推荐了,返回首页