React 官方文档学习

React 官方文档学习

渲染DOM元素和更新DOM元素

  1. ReactDOM.render(element1,element2)
    解释:该函数用于将element1 渲染到 element2中,而element2 也就是React一般说的根节点。React会将element2中的内容替换成element1的内容。
    如果不断调用该函数来生产新的UI元素,React就会比较新旧元素的区别而实际只更改这两个元素的不同点。

组件、Props\state

编写React组件可以通过两种方式来进行封装,一种是通过JavaScript函数来进行封装,一种是通过ES6的Class来定义组件。
官方的例子如下

//JS函数
function Welcome(props) {
  return <h1>Hello, {props.name}</h1>;
}
//ES6 Class
class Welcome extends React.Component {
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

上面的例子只是一个简单的React组件的示例,其中JS函数和ESClass格式下的组件返回的是一个React元素,而函数中的props则是用来接收外来的参数的。
React会将JSX所接收的属性(attributes)和子组件(children)转化为单个对象,并称为 props
ESClass组件每一次更新都会调用自身的render()方法。

{
attributes1:value1,
attributes2:value2
}

Props 的只读性
组件无论是函数声明还是Class声明,都不可以修改自身的props。如果想要通过修改props来实现动态想过则需要借助State,State可以帮助我们完成这一操作。
State
如何使用State(还是用上面的例子进行讲解)

//首先我们需要跟Class添加初始化函数,并对state进行初始化
class Welcome extends React.Component {
  constructor(props){
  	//1.将props 传递到父类的构造函数中,不然可以无法通过this.props 来获取数据
  	super(props);
  	//2.初始化this.state,也就是赋初值
  	this.state={date:new Date()};
  }
  render() {
    return <h1>Hello, {this.props.name}</h1>;
  }
}

完成以上的操作,就可以通过this.state来操作props里的值,而不需要直接操作props了。但是这个操作并不是直接修改props里的值,而是类似于对props进行了一个复制,我们操作的是复制值。
关于this.state需要注意的点:
(1)除了构造函数中外的其他地方如下赋值是毫无意义的

this.state.xxxx = 'xxxxx'; 
//应该如下赋值
this.setState({xxxx : 'xxxx'});

(2)state 的更新可能是异步的
一般来讲,React处于性能考虑,并不会一次次的加载setState函数,而是可能把多个setState函数合并成一个来调用,所以this.propsthis.state 可能会异步更新,从而导致错误,如下同时调用this.propsthis.state 时。

this.setState({
  counter: this.state.counter + this.props.increment,
});

要解决这个问题,我们就需要让setState接收的是一个函数而不是对象。如下

this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

(3)state 的更新会合并
当调用setState 时,React会把你提供的对象合并到当前的state中,但是并不会修改其他的参数。

Class中的部分生命周期函数

要了解React的这部分生命周期函数,首先我们需要了解两个概念。
挂载(mount):到组件第一次被渲染到DOM中时,称之为挂载。
卸载(unmount):当组件被删除时,成为卸载。
这里要介绍的两个生命周期函数就是当组件被挂载或者卸载时调用的函数。
componentDidMount()componentWillUnmount()

事件处理

React 中不能使用 false来阻止默认行为,而是通过preventDefault来实现,具体示例如下:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

为了在回调中可以调用this来调用函数,我们必须在初始话函数中添加如下字段来保证初始化成功。

this.handleClick = this.handleClick.bind(this);

在render中返回 null 表示的意思是该组件不渲染。

状态提升

状态提升,按照我的理解就是:将组件中的部分方法指向父组件方法,但是值还是使用当前组件内的数据。
参考官方文档的示例:

class TemperatureInput extends React.Component {
  constructor(props) {
    super(props);
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(e) {
    this.props.onTemperatureChange(e.target.value);
  }

  render() {
    const temperature = this.props.temperature;
    const scale = this.props.scale;
    return (
      <fieldset>
        <legend>Enter temperature in {scaleNames[scale]}:</legend>
        <input value={temperature}
               onChange={this.handleChange} />
      </fieldset>
    );
  }
}
class Calculator extends React.Component {
  constructor(props) {
    super(props);
    this.handleCelsiusChange = this.handleCelsiusChange.bind(this);
    this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this);
    this.state = {temperature: '', scale: 'c'};
  }

  handleCelsiusChange(temperature) {
    this.setState({scale: 'c', temperature});
  }

  handleFahrenheitChange(temperature) {
    this.setState({scale: 'f', temperature});
  }

  render() {
    const scale = this.state.scale;
    const temperature = this.state.temperature;
    const celsius = scale === 'f' ? tryConvert(temperature, toCelsius) : temperature;
    const fahrenheit = scale === 'c' ? tryConvert(temperature, toFahrenheit) : temperature;

    return (
      <div>
        <TemperatureInput
          scale="c"
          temperature={celsius}
          onTemperatureChange={this.handleCelsiusChange} />
        <TemperatureInput
          scale="f"
          temperature={fahrenheit}
          onTemperatureChange={this.handleFahrenheitChange} />
        <BoilingVerdict
          celsius={parseFloat(celsius)} />
      </div>
    );
  }
}

组合

对于一些组件,可能我们对于其内部的部分区域即将会展示什么部分没有明确的设计,而我们却希望我们将来可以直接添加这一部分的组件内容,所以组合的概念也就应运而生了。这个的概念和Vue.js中的插槽(solt)有些类似。
对于React,我们通过props.children这个参数来将他们的子组件传递到渲染结果中。

function FancyBorder(props) {
  return (
    <div className={'FancyBorder FancyBorder-' + props.color}>
      {props.children}
    </div>
  );
}

如果其他组件想要在其中插入子组件的话可以进行如下的编码

function WelcomeDialog() {
  return (
    <FancyBorder color="blue">
      <h1 className="Dialog-title">
        Welcome
      </h1>
      <p className="Dialog-message">
        Thank you for visiting our spacecraft!
      </p>
    </FancyBorder>
  );
}

但是prop.children 只是适用于只有一个添加点的情况,当拥有多个添加点的时候,我们就可以通过自定义的方式来达到我们的需求:

function SplitPane(props) {
  return (
    <div className="SplitPane">
      <div className="SplitPane-left">
        {props.left}
      </div>
      <div className="SplitPane-right">
        {props.right}
      </div>
    </div>
  );
}

function App() {
  return (
    <SplitPane
      left={
        <Contacts />
      }
      right={
        <Chat />
      } />
  );
}

React组件的更新

由于React组件是无法改变的元素,一旦创建就无法修改。所以要实现更新组件的功能,只能将原有的组件进行卸载并重新创建一个元素。

ReactDOM.unmountComponentAtNode(div);//卸载组件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值