一直忙于审核的问题,更新内容如下

  • 栏目:基础 时间:2020-04-15 11:17
<返回列表

React 16.10.0 发布了,更新内容如下:

概述

目前,我需要在应用界面上实时显示日期(精确到秒),该如何处理?
按照React的规则,传递给组件的props对象只能读,而实时日期是实时更新的,那就只有实时的调用组件传递不同的props值,当然,这可以通过设置一个定时器实现,定时调用ReactDOM.render(),传递不同的参数给props来改变输出。如果只是这样,那用JavaScrip就能实现,并不能体现React的简洁与高效。

时间过的真快,距离上次的技术研究成果已有近一月未更新了,回想这一个多月以来。一直忙于审核的问题,并与苹果审核员斗智斗勇!

React DOM

定时器实现

function tick() {
  const element = (
    <div>
      <h1>Hello, world!</h1>
      <h2>It is {new Date().toString('yyyy-MM-dd HH:mm:ss')}</h2>
    </div>
 );
  ReactDOM.render(
    element,
    document.getElementById('root')
 );
}
setInterval(tick, 1000);

每隔1s调用一次tick方法,获取改变后的元素,重新渲染。
如果仅仅这样的话,组件是没法重用的。
现将<h1>Hello, world!</h1>和<h2>It is {new Date().toString('yyyy-MM-dd HH:mm:ss')}</h2>分别抽象成一个展示欢迎的函数组件和一个展示时钟的组件:

function Welcome(props) {
    return <h1>hello, {props.name}</h1>;
}
function Clock(props){
    return <h2>It is {props.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
}
function tick() {
  const element = (
    <div>
      <Welcome name= "world" />
      <Clock date={new Date()} />
    </div>
 );
  ReactDOM.render(
    element,
    document.getElementById('root')
 );
}
setInterval(tick, 1000);

从上可以看到,Welcome和Clock组件得到了复用。但是还不够好,因为:
1.ReactDOM.render()每秒都会执行一次,其实我只希望它执行一次,因为真正需要改变的是Clock组件;
2.Welcome组件每秒都会执行一次,但是它的内容无任何变化;
真正需要的是ReactDOM.render()只执行一次,时钟的变化交由Clock组件自身完成。

业余时间研究了下React Native,嘿发现还不错哦!至少能够解决苹果审核的更新问题,减少上线拖延对公司的损失,虽然会有少许弱化性能的问题。但是已经是很大进步了!

Scheduler(实验性)

state实现

本篇,站在对React Native一知半解或者没听说过React Native的小白立场上对React Native 的基本介绍与在苹果平台搭建测试iOS设备方面进行相应的介绍!

useSubscription

更新说明及下载地址

React 16.10.1 修复了一个 bug:

1.将Clock函数组件改成类组件

你可以通过5个步骤将函数组件 Clock 转换为类
==创建一个名称扩展为 React.Component 的ES6 类
==创建一个叫做render()的空方法
==将函数体移动到 render() 方法中
==在 render() 方法中,使用 this.props 替换 props
==删除剩余的空函数声明

class Clock extends Component{
    render(){
        return <h2>It is {this.props.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

亲测可用哦!

React DOM

更新说明及下载地址

(文/开源中国)    

2.给Clock类添加局部状态

在 render() 方法中使用 this.state.date 替代 this.props.date

class Clock extends Component{
    render(){
        return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

一.React Native是什么?
1.React 与Native的关系:
React是Facebook推出的一款JaveScript框架,目的是为了前端开发所用!
React :Web应用开发
React.js:JaveScript开发语言
ReactNative:App移动应用开发

3.添加一个类构造函数来初始化状态 this.state

class Clock extends Component{
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
   }

    render(){
        return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

注意我们如何传递 props 到基础构造函数的:

constructor(props) {
        super(props);
        this.state = {date: new Date()};
   }

类组件应始终使用props调用基础构造函数。

2.与我们移动开发有什么关系?
原生开发:iOS 或者 Android开发
混合开发:Hybrid App(原生Api + Html开发)
React Native开发:
原生开发最大劣势:热更新问题(特别是iOS),还有不能跨平台;
混合开发最大劣势:性能不好;

4.将定时器移到Clock组件本身

class Clock extends Component{
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
   }​
    tick() {
        this.setState({
            date: new Date()
       });
   }
    render(){
        return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

3.React Native为何能够用于移动端开发原因:
在于虚拟DOM原理:
DOM是什么,可以理解为HTML下的一个一个的页面:
React Native不直接操作DOM,数据发生变化,需要刷新时,React首先创造虚拟DOM,通过一定的机制比对比出改变的DOM,之后再只对改变的DOM进行刷新操作,而不是像原生Web一样全部刷新DOM,从而提高了性能。

5.从 <Clock /> 元素移除 date 属性

const element = (
    <div>
        <Welcome name= "world" />
        <Clock />
    </div>
);
ReactDOM.render(
    element,
    document.getElementById('root')
);

4.汇总React Native 的优缺点与使用场景:
优点:跨平台,投资少,热更新,全栈性;
缺点:性能比原生App弱一丢丢而已!

6.给组件添加生命周期函数

class Clock extends Component{
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
   }
    tick() {
        this.setState({
            date: new Date()
       });
   }
    componentDidMount(){
        //
   }
    componentWillUnmount(){
        //
   }
    render(){
        return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

这些生命周期函数称作生命周期钩子。
当组件输出到 DOM 后会执行 componentDidMount() 钩子,即组件渲染到DOM后执行,此处一般用来加载数据的,但只执行一次,可以把定时器设置在此处:

componentDidMount(){
        // 装载定时器
        this.timerID = setInterval(
           () => this.tick(),
            1000
       );
   }

每秒执行一次tick,而tick方法则是通过this.setState更改局部状态date。
保存定时器ID,卸载时用到。
this.props由React本身设置,this.state具有特殊的含义,但如果需要存储不用于视觉输出的东西,则可以手动向类中添加其他字段。
如果你不在render()中使用某些东西,它就不应该在状态中。// 理论上是这样,但有时为了控制状态,也可以定义一些不用在render中使用的字段。
我们将在 componentWillUnmount()生命周期钩子中卸载计时器:

componentWillUnmount(){
        // 卸载定时器
        clearInterval(this.timerID);
   }

看看完整的代码:

import React, { Component } from 'react';
import ReactDOM from 'react-dom';
function Welcome(props) {
    return <h1>hello, {props.name}</h1>;
}

class Clock extends Component{
    constructor(props) {
        super(props);
        this.state = {date: new Date()};
   }
    tick() {
        this.setState({
            date: new Date()
       });
   }
    componentDidMount(){
        // 装载定时器
        this.timerID = setInterval(
           () => this.tick(),
            1000
       );
   }
    componentWillUnmount(){
        // 卸载定时器
        clearInterval(this.timerID);
   }

    render(){
        return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
   }
}

const element = (
    <div>
        <Welcome name= "world" />
        <Clock />
    </div>
);
ReactDOM.render(
    element,
    document.getElementById('root')
);

此时,你可以看到浏览器每秒更新一次时钟。是不是很酷很神奇?
那这个过程是怎么实现的呢?
1.当<Clock />被传递给ReactDOM.render()时,React调用Clock组件的构造函数,由于Clock需要显示当前时间,所以使用包含当前时间的对象来初始化this.state。
2.React调用Clock组件的render()方法渲染屏幕,然后React更新DOM以匹配Clock的渲染输出。
3.当Clock的输出插入到DOM中时,React调用componentDidMount()生命周期钩子。在其中,Clock组件要求浏览器设置一个定时器,每秒钟调用一次tick()。
4.浏览器每秒钟调用tick()方法。 在其中,Clock组件通过使用包含当前时间的对象调用setState()来调度UI更新。 通过调用setState(),React 知道状态已经改变,并再次调用render()方法再次渲染屏幕。 而这次,render()方法中的this.state.date将不同,所以渲染输出将包含更新的时间,并相应地更新DOM。// 你会发现并不会再调用componentDidMount,因为该函数只在第一次装载的时候调用。
5.一旦Clock组件被从DOM中移除,React会调用componentWillUnmount()这个钩子函数,定时器也就会被清除。
从上可知Clock组件中3个方法的执行顺序:
constructor 组件调用时
render 组件调用时,state变化后调用
componentDidMount 组件装载后
componentWillUnmount 组件卸载后

二.搭建Mac下的React Native 的步骤:
这里的安装步骤可以参考后面的链接,但建议参考本人的,因为其中有本人爬过的坑,以及避坑策略和部分连接中无关软件没必要安装等。

正确地使用状态

状态(state)很灵活,也很实用,但使用时需要注意,不然,很有可能得不到想要的结果。
1.不要直接更新状态

this.state.date = new Date();

此时你可以看到,时钟并不会更新。
应该使用this.setState()函数。
构造函数是唯一能够初始化this.state的地方。
2.状态更新可能是异步的
React 可以将多个setState() 调用合并成一个调用来提高性能。
因为 this.props 和 this.state 可能是异步更新的,你不应该依靠它们的值来计算下一个状态。
例如,此代码可能无法更新计数器:

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

要修复它,请使用第二种形式的 setState() 来接受一个函数而不是一个对象。 该函数将接收先前的状态作为第一个参数,将需要更新的值作为第二个参数:

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

上方代码使用了箭头函数,但它也适用于常规函数:

this.setState(function(prevState, props) {
  return {
        counter: prevState.counter + props.increment
 };
});

箭头函数后续会说到。
3.状态更新合并
当你调用 setState() 时,React 将你提供的对象合并到当前状态。
你可以调用 setState() 独立地更新它们。
数据自顶向下流动
父组件或子组件都不能知道某个组件是有状态还是无状态,并且它们不应该关心某组件是被定义为一个函数还是一个类。
这就是为什么状态通常被称为局部或封装。 除了拥有并设置它的组件外,其它组件不可访问。
组件可以选择将其状态作为属性传递给其子组件:

<h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>

这也适用于用户定义的组件:

<FormattedDate date={this.state.date} />

FormattedDate 组件将在其属性中接收到 date 值,并且不知道它是来自 Clock 状态、还是来自 Clock 的属性、亦或手工输入:

function FormattedDate(props) {
  return <h2>It is {this.state.date.toString('yyyy-MM-dd HH:mm:ss')}</h2>;
}

这通常被称为自顶向下或单向数据流。
任何组件状态由组件本身所有,并且只能传递到树中下方的组件。
为了表明所有组件都是真正隔离的,我们可以在element元素中同时渲染三个Clock:

const element = (
    <div>
        <Welcome name= "world" />
        <Clock />
        <Clock />
        <Clock />
    </div>
);

ReactDOM.render(
    element,
    document.getElementById('root')
);

每个 Clock 建立自己的定时器并且独立更新。
在React应用程序中,组件是有状态还是无状态被认为是可能随时间而变化的组件的实现细节。可以在有状态组件中使用无状态组件,反之亦然。

注:
本教程相关的所以源码,可在https://github.com/areawen2GHub/reacttest.git下载

参考地址:
https://react.bootcss.com/react/docs/state-and-lifecycle.html

以下为部分操作命令成功后展示(没有成功前不是这么简单,一般都会有大量的输出哦!):

韦德体育 1

命令用法展示.png

1.安装Homebrew
打开终端,输入以下命令:

/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

注意:如果安装有/usr/local目录不可写的权限问题,可以用下面的命令修复

sudo chown -R `whoami` /usr/local

2.更改环境下载源
注意:这个步骤不是必须的,但是为了加快下载的速度所做,不要用cnpm安装(如淘宝源的问题等)。
参考这个网站中 http://ban.ninja 更改源的命令
分别使用如下命令(2个命令执行其一即可)

vi   ~/.bash_profile
vi   ~/.bashrc

打开对应的源文件,看那一个文件中显示的是以export开头的语句,添加下面这句话到对应的文件中。

export HOMEBREW_BOTTLE_DOMAIN=http://7xkcej.dl1.z0.glb.clouddn.com

按下Esc快捷键,同时,输入“:”,wq(保存),如此完成环境源的下载路径配置。

3.安装Yarn:即react native 的命令行工具(react-native-cli)
执行下面的命令,安装Yarn:

npm install -g yarn react-native-cli

安装yarn后设置镜像源,连续执行下面2个命令:

yarn config set registry https://registry.npm.taobao.org --global
yarn config set disturl https://npm.taobao.org/dist --global

如果报错EACCES: permission denied,也要类似安装homebrew时的情况一样,修复/usr/local目录命令如下:
(没报错的话请忽略)。

sudo chown -R `whoami` /usr/local

4.推荐安装工具如 Watchman
采用如下命令安装:

brew install watchman

5.推荐使用WebStorm 或Sublime Text 编辑器来编写React Native应用的代码。

6.创建 我们的第一个App的项目:
如下命令:

react-native init MyApp(我的项目名称)  --version 0.44.3

其中创建App项目最好加上--version 0.44.3 ,可以创建低一点的版本,否则默认创建最新的版本,即高版本,需要的代码更多一些,所以下载速度慢
有时候会出现部分文件没下载完全,就会出现找不到文件的报错。
此乃我爬过的神坑!

7.运行并测试项目:
进入我们的项目

cd MyApp/

如果第一次使用的话:

react-native run-ios

小技巧:若run-ios执行不成功,需要用Xcode打开我们的项目,也可以在第一次运行iOS模拟器之后,使用cmd +R来处理。

react-native start

最后附上我第一次运行成功之后的截图:

韦德体育 2

挺有成就感哈!.png

韦德体育 ,三.编制我们的第一个React Native的程序:
代码如下:

// 1.第一个项目Hello World!
//  引入依赖
import React,{Component} from 'react';
import {AppRegistry,Text} from 'react-native';

// Hello 相当于一个组件
// Component 基本组件
class Hello extends Component {

  // 返回渲染内容
  render() {
    return (<Text >Hello world!</Text>);
  }
}

// 注册项目的根组件:第一个参数为项目名称 ,第二个参数为注册的基本组件
AppRegistry.registerComponent('MyDemo',() =>Hello);

最后附上自己参考学习的资料:
React Native 中文网:
http://reactnative.cn/docs/0.47/getting-started.html#content
欢迎交流,后续会把关于React Native 的 控件,Props ,State,热更新等问题一并解决,共同学习吧!

上一篇:没有了 下一篇:开源运动是自由软件运动的非道德、去政治化替代,极端资本主义声称利润证明任何手段都是合理的

更多阅读

一直忙于审核的问题,更新内容如下

基础 2020-04-15
React 16.10.0 发布了,更新内容如下: 概述 目前,我需要在应用界面上实时显示日期(精确到秒...
查看全文

开源运动是自由软件运动的非道德、去政

基础 2020-04-15
近期自由软件运动发起人 RMS 受邀在微软进行了演讲,RMS在其博客中介绍了他在演讲中发表的...
查看全文

韦德体育Linux Mint 19.3 发行版则计划在今年

基础 2020-04-15
Linux Mint 的负责人 Clement Lefebvre最新发布了该项目的每月新闻,并透露出一些关于 LMDE4 和 Lin...
查看全文

友情链接: 网站地图

Copyright © 2015-2019 http://www.koi-bumi.com. 韦德体育有限公司 版权所有