客户端高性能组件化框架React简介、特点、环境搭建及常用语法

明天就是春节了

预祝大家新春快乐 [ ]~( ̄▽ ̄)~*

天天饭局搞得我是身心疲惫= =

所以更新比较慢

今天想跟大家分享的就是这个大名鼎鼎的React框架

简介

React是这两年非常流行的框架

并不难,还是挺容易上手的

起源于Facebook内部项目(一个广告系统)

传统页面从服务器获取数据,显示到浏览器上,用户输入数据传入服务器

但随着数据量增大,越来越难以维护了

Facebook觉得MVC不能满足他们的扩展需求了(巨大的代码库和庞大的组织)

每当需要添加一项新的功能或特性时,系统复杂度就几何增长

致使代码脆弱不堪、不可预测,结果导致他们的MVC正走向崩溃

当系统中有很多的模型和相应视图时,其复杂度就会迅速扩大,非常难以理解和调试

总之就是Facebook对市场上所有JS-MVC框架都不满意,认为都不适合大规模应用

就自己写了一套,用来架设Instagram网站

写完后用着用着,发现哎呦这货还真是不错,然后就开源了

随着这几年的沉淀,React已经变得越来越强大了

MVC

科普一下MVC

MVC就分为M、V、C三部分

  • Model(模型):

    应用程序中用于处理应用程序数据逻辑的部分。通常负责在数据库中存取数据

  • View(视图):

    应用程序中处理数据显示的部分。通常依据模型数据创建

  • Controller(控制器):

    应用程序中处理用户交互的部分。通常负责从视图读取数据,控制用户输入,并向模型发送数据

简单的理解一下

我们就是user,在页面中点击了一个按钮触发了事件

控制器Controller调整数据,模型Model中数据改变

数据改变又会导致视图View更新

UI的改变反馈呈现给我们user



这里还要说明一下,虽然介绍了MVC

但是React不是MVC框架

而是用于构建组件化UI的库,是一个前端界面开发工具

顶多算作MVC中的View视图

而且MVC更多的是数据双向绑定

但我们React是单向数据流

框架特点

React它具有以下特点

  • 高性能

    传统web页面操作DOM涉及重绘重排相当耗性能,React 提供了一种不同而又强大的方式来更新DOM(轻量级虚拟Dom——Virtual Dom),代替直接操作DOM

    又使用diff算法,更新virtual dom时不保证马上影响真实dom,react会等到事件循环结束,利用diff算法,通过当前新dom表述与之前做比较,计算出最小步骤更新真实dom

  • 组件化

    Dom树上的节点称为元素,而虚拟Dom(整体称component) 的节点称作组件(可复用性)

  • 可预测性

    state属性包含定义组件所需要的一些数据,当数据发生变化时,将会调用Render重现渲染

    React 把组件看成是一个状态机(State Machines)

    通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致

  • 单向数据流

    数据从父节点传递到子节点,只需要从父节点获取props渲染即可

环境搭建

我选择使用webpack搭建环境

关于webpack就不多说了,提一下重点

这是我的webpack.config.js配置文件

module.exports = {
    entry: {
        index: ‘./src/js/entry.js‘
    },
    output: {
        path: ‘./static/dist/‘,
        publicPath: ‘http://localhost:8080/static/dist/‘,
        filename: ‘[name].js‘
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                loader: ‘babel‘,
                query: {
                    presets: [‘react‘, ‘es2015‘]
                }
            },
            {
                test: /.less$/,
                loader: ‘style!css!less‘
            }
        ]
    }
}

这里的关键就是除了要安装babel-loaderbabel-core

还要安装babel-preset-es2015babel-preset-react

用于解析ES6语法(为了老版本浏览器)和React的JSX语法

还有reactreact-dom也是必须要下载的



全部依赖模块在这里

"devDependencies": {
  "babel-core": "^6.22.1",
  "babel-loader": "^6.2.10",
  "babel-preset-es2015": "^6.22.0",
  "babel-preset-react": "^6.22.0",
  "css-loader": "^0.26.1",
  "less": "^2.7.2",
  "less-loader": "^2.2.3",
  "react": "^15.4.2",
  "react-dom": "^15.4.2",
  "style-loader": "^0.13.1",
  "webpack": "^1.14.0",
  "webpack-dev-server": "^1.16.2"
}

JSX

简单说一下React的JSX语法是个神马东西

可能一会儿大家会看大不明觉厉的代码

比如

return (
    <div>hehe<div>
)

这就是JSX代码,它是React提供的语法糖

是React的重要组成部分,使用类似XML标记的方式来声明界面及关系

语法糖的意思我写ES6的时候也说了

就是计算机语言中添加的语法,对语言的功能没影响

方便我们开发人员使用的,可以增强可读性

如果使用JS代码也可以,不过官方推荐使用JSX

这样来写,结构层次关系都很清晰

webpack会帮我们把他们转换成浏览器认识的js代码(loader的作用)

(如果好奇转换成了什么,可以去webpack输出文件查看,或者找jsx转js的工具)



JSX语法结构说的通俗一点就是HTML、JS混写

可能大家会有疑惑,说好的结构、样式、行为相分离的前端思想呢?!

React其中一个主要的设计理念是编写简单容易理解的代码

但我们的组件确实不好松耦合

大家也不要过分较真



这样的语法结构是怎样解析的呢?其实并不神奇

JSX的语法规则:

  • 遇到 HTML 标签(以 < 开头),就用 HTML 规则解析
  • 遇到代码块(以 { 开头),就用 JavaScript 规则解析
  • 代码块中如果只有一个数组变量,就展开这个数组的所有成员

不理解不要慌,看了下面就懂了

提前渗透一下

渲染到页面

终于写到语法正题了

在此之前我们必须要引用的两个对象

一个React核心对象和一个React-Dom对象

var React = require(‘react‘);
var ReactDom = require(‘react-dom‘);


ReactDom.render()是react最最基本的方法

所以我放到最开始来讲

它通过ReactDom将我们的组件渲染到页面

我在页面中添加一个节点

<div id="root"></div>

现在页面中什么也没有

不过马上就有了

ReactDom.render(
    <h1>Demo</h1>,
    document.getElementById(‘demo‘)
);

第一个参数是要插入的虚拟DOM

第二个参数就是要渲染的DOM节点

(React不建议直接添加到body标签document.body)

页面中出现了“Demo”

实际上react将我们的节点插入到了div节点的内部

组件

React的一大特点就是组件化

React组件有以下特点

  • 组合:简单组件可组合为复杂组件
  • 重用:组件独立,可被多个组件使用
  • 测试:组件独立,便于测试
  • 维护:UI和组件相关逻辑都封装在组件内部,便于维护

组件生成

React.createClass()就是用于将代码封装成组件Component的方法

它会生成一个React组件

var App = React.createClass({
    render: function(){
        return (
            <p>This is a component...</p>
        )
    }
});

这个方法参数是一个对象

对象中有一个render返回一个虚拟DOM

render是输出组件必须要写的(关于它下面还会再说)

先记住两点

  • 组件名首字母一定大写,否则会报错
  • 输出的组件只能有一个顶级标签,其他标签会失效

所以各位,下面的写法都是不对的

//错误的写法
var app = React.createClass({
    render: function(){
        return <p>This is a component...</p>
    }
})
//错误的写法
var App = React.createClass({
    render: function(){
        return (
            <p>This is a component...</p>
            <p>This is also a component...</p>
        )
    }
});

组件两边加括号的目的,是防止JavaScript自动分号机制产生问题

组件渲染

生成的组件要想渲染到页面

就使用我们刚讲完的ReactDom.render( )

ReactDom.render(
    <App></App>,
    document.getElementById(‘root‘)
);

组件要写成标签的形式

这里我们就要写<App></App>或者单标签形式<App/>也可以

组件特性

为了加以区分,我把标签的属性叫组件特性

var App = React.createClass({
    render: function(){
        return <p name="demo">This is a component...</p>;
    }
});
ReactDom.render(
    <App></App>,
    document.getElementById(‘root‘)
);

还要注意两个特例

  • class要写成className
  • for要写成htmlFor

因为他们是JavaScript的保留字



如果想要为组件添加内联样式,可以这样写

var App = React.createClass({
    render: function(){
        var styles = {
            color: ‘#fff‘,
            backgroundColor: ‘#000‘
        }
        return <p className="demo" style={styles}>This is a component...</p>; // <--
    }
});
ReactDom.render(
    <App></App>,
    document.getElementById(‘root‘)
);

声明了一个styles对象

但是将它添加到属性时,要使用 { }

因为JSX语法中,html中使用js就必须使用大括号

下面就不再赘述了

组件属性

this.props

组件的属性同样可以像html一样添加<App name="payen"></App>

并且这个组件属性内部可以通过this.props对象获取

var App = React.createClass({
    render: function(){
        return <p>name:{this.props.name} age:{this.props.age}</p>;
    }
});
ReactDom.render(
    <App name="payen" age="20"></App>, // <--
    document.getElementById(‘root‘)
);



了解了这个,我们可以做一个小练习

现在有一组数据,利用它组成一个有序列表组件

var data = [‘Mr.A‘,‘Mr.B‘,‘Mr.C‘];

可以将这个数组成为组件属性

然后利用this.props.data获取数据

最后使用ES5数组的map方法就大功告成了

var List = React.createClass({
    render: function(){
        return (
            <ol>
                {
                    this.props.data.map(function(item, index){
                        return <li key={1000 + index}>{item}</li>;
                    })
                }
            </ol>
        )
    }
});
ReactDom.render(
    <List data={data}></List>,
    document.getElementById(‘root‘)
);

还要注意<li key={1000 + index}>{item}</li>

key值如果不写的话,虽然可以正常渲染

但会警告我们数组或迭代器的每一项都应该有一个独一无二的key值

这里我就使用了1000加上索引的形式添加了key值

this.props.children

通常组件的属性与this.props对象中的属性是一一对应的

但有一个例外,它是this.props.children

它表示我们组件的所有子节点

什么意思呢?接着我们上面的例子

我们在List组件中添加一些子节点

修改ReactDom.render( )方法的参数

ReactDom.render(
    <List data={data}>
        <span>Mr.D</span>
        <span>Mr.E</span>
    </List>,
    document.getElementById(‘root‘)
);

我们发现页面中并没有什么变化,但浏览器也没有报错

这时我们需要使用this.props.children

var data = [‘Mr.A‘,‘Mr.B‘,‘Mr.C‘];
var List = React.createClass({
    render: function(){
        console.log(this.props.children);
        return (
            <ol>
                {
                    this.props.data.map(function(item, index){
                        return <li key={1000 + index}>{item}</li>;
                    })
                }
                {
                    this.props.children
                }
            </ol>
        )
    }
});
ReactDom.render(
    <List data={data}>
        <span>Mr.D</span>
        <span>Mr.E</span>
    </List>,
    document.getElementById(‘root‘)
);

如此页面中就显示出了子节点

这个this.props.children很奇怪,它有三种类型值

  • 没有子节点,值为undefined
  • 有一个子节点,值为object对象
  • 有多个子节点,值为array数组

(可以在控制台上输出验证)

所以我们处理它要特别小心

好在我们可以使用React给我们提供的方法

利用React.Children.map( )我们就可以放心遍历处理子节点

var data = [‘Mr.A‘,‘Mr.B‘,‘Mr.C‘];
var List = React.createClass({
    render: function(){
        return (
            <ol>
                {
                    this.props.data.map(function(item, index){
                        return <li key={1000 + index}>{item}</li>;
                    })
                }
                {
                    React.Children.map(this.props.children,function(child){
                        return <li>{child}</li>
                    })
                }
            </ol>
        )
    }
});
ReactDom.render(
    <List data={data}>
        <span>Mr.D</span>
        <span>Mr.E</span>
    </List>,
    document.getElementById(‘root‘)
);

propTypes( )

组件的属性可以接受任何值,数字、字符串、函数、对象什么都可以

但有时候,我们拿到一个组件,想要验证参数是否符合我们的要求(这其实很重要,不要轻视)

这时就需要使用组件的propTypes( )方法和React.PropTypes配合验证了

var data = [‘Mr.A‘,‘Mr.B‘,‘Mr.C‘];
var App = React.createClass({
    propTypes: {
        data: React.PropTypes.array
    },
    render: function(){
        return (
            <div>{this.props.data}</div>
        )
    }
});
ReactDom.render(
    <App data={data}></App>,
    document.getElementById(‘root‘)
);

这里我期望的data属性值为array数组类型

没有任何问题,因为我们传入的就是数组

可是如果改成期望字符串类型data: React.PropTypes.string

浏览器就会发出警告

详细见React中文官网:Prop 验证

组件嵌套

还记得React单向数据流的特点么

也就是说我们应该把数据传递给父节点

父节点通过this.prop将数据传递给子节点

子节点再通过自己的this.prop处理收到的数据

var data = [‘Mr.A‘,‘Mr.B‘,‘Mr.C‘];
var List = React.createClass({
    render: function(){
        return (
            <ol>
                {
                    this.props.data.map(function(item, index){
                        return <li key={1000 + index}>{item}</li>;
                    })
                }
            </ol>
        )
    }
});
var App = React.createClass({
    render: function(){
        return (
            <div>
                <List data={this.props.data}></List>
            </div>
        )
    }
});
ReactDom.render(
    <App data={data}></App>,
    document.getElementById(‘root‘)
);

所呈现的DOM结构

生命周期

生命周期不难理解

组件的一生无非就是产生、更新、销毁

在组件的每一个生命周期内,都会按顺序触发一些组件方法

比如我们刚刚的render方法就会在产生和更新的阶段都会触发

具体触发的回调函数API以及作用给大家整理在下面

(关于它们在整个生命周期的触发次数大家应该都能想明白就不写了)

(不常用的我在后面的标注了*号)

  • 组件实例化Mouting【组件生成时触发】

    • getDefaultProps( )

      • 作用于组件类,返回对象用于设置默认的this.props(引用值会在实例中共享)
      • e,g.return {name: ‘payen‘} 相当于初始化了组件属性this.props.name = ‘payen‘
    • getInitialState( )
      • 作用于组件的实例,返回对象作为this.state的初始值
      • e,g.return {show: false} 相当于初始化了组件状态this.state.show = false
    • componentWillMount( )
      • 首次渲染前调用,可做一些业务初始化操作,也可以通过this.setState()设置组件状态
      • e,g.this.setState({show: false})
    • render( )
      • 必选方法,用于创建虚拟DOM,有特殊规则(再啰嗦一遍)

        • 只能通过this.props和this.state访问数据
        • 可以返回null、false或任何React组件
        • 只能出现一个顶级组件(不能返回数组)
        • 不能改变组件的状态
        • 不能修改DOM的输出
    • componentDidMount( )(服务器端不会调用)
      • 真实DOM被渲染后调用,可通过this.getDOMNode()访问到真实的DOM元素

        此时可使用其他类库来操作该DOM

  • 组件存在期Updateing【组件更新时触发】(state,props变化触发)
    • componentWillReceiveProps( )*

      • 组件接收新props时调用,并将其作为参数nextProps使用,此时可以更改组件props及state
    • shouldComponentUpdate( )*
      • 组件是否应当渲染新props或state

        返回false表示跳过后续生命周期方法(通常不需要使用以避免出现bug)

        在出现应用瓶颈时,可通过该方法进行适当的优化。

        在首次渲染期间或者调用了forceUpdate方法后,该方法不会被调用

    • componentWillUpdate( )
      • 接收到新props或state后,进行渲染前调用,此时不允许更新props或state
    • render( )
      • 不再赘述
    • componentDidUpdate( )*
      • 完成渲染新的props或state后调用,此时可以访问到新的DOM元素
  • 组件销毁期Unmounting【组件销毁时触发】
    • componentWillUnmount()*

      • 组件移除前调用,可用于做一些清理工作

        在componentDidMount中添加的所有任务都需要在该方法中撤销(e.g.定时器、事件监听器等等)

附上一张我盗的图,帮助大家理解(手动滑稽)

关于这些API更详细的信息

建议大家可以去React中文官网查看:Component Specs and Lifecycle

组件状态

上面提到了this.state,和我们之前介绍的this.props一样重要

不过this.props通常不会变,但this.state会变

就如其字面意思,表示组件的状态

这个属性是只读的

所以设置状态我们需要使用this.setState( )

可使用this.setState( )的方法:

componentWillMount、componentDidMount、componentWillReceiveProps

组件交互

在此之前我们需要了解的就是React的事件系统

JavaScript原始行间绑定事件都是普遍小写<button onclick="clickHandle()"></button>

但我们在React中要使用驼峰写法<button onClick="clickHandle()"></button>

React的事件处理器会传入虚拟事件对象的实例(一个对浏览器本地事件的跨浏览器封装)

它有和浏览器本地事件相同的属性和方法,包括 stopPropagation() 和 preventDefault(),

但是没有浏览器兼容问题

详细支持事件见中文官网:事件系统-支持的事件



现在我们要来实现这样一个简单的功能

点击按钮,出现弹框

单击弹框,弹框消失

先来实现结构与样式

var App = React.createClass({
    render: function(){
        return (
            <div>
                <button>点击</button>
                <PopUp></PopUp>
            </div>
        )
    }
});
var PopUp = React.createClass({
    render: function(){
        var styles = {
            position: ‘absolute‘,
            left: ‘40px‘,
            top: ‘40px‘,
            width: ‘100px‘,
            height: ‘100px‘,
            backgroundColor: ‘#f40‘
        }
        return (
            <div className="popup" style={styles}></div>
        )
    }
})
ReactDom.render(
    <App/>,
    document.getElementById(‘root‘)
);



首先我们先来实现第一个功能:点击按钮出现弹框

问题是如何实现

我们的React是单向数据流

父级向子级传递数据

最好的办法就是在父级设置组件状态this.state

将状态通过组件属性this.props传递给子级

这样点击事件要做的就是改变父级状态

子级状态也会随之改变

var App = React.createClass({
    getInitialState: function(){
        return {
            open: false
        }
    },
    buttonHandler: function(){
        this.setState({
            open: true
        });
    },
    render: function(){
        return (
            <div>
                <button onClick={this.buttonHandler}>点击</button>
                <PopUp open={this.state.open}></PopUp>
            </div>
        )
    }
});
var PopUp = React.createClass({
    render: function(){
        var styles = {
            position: ‘absolute‘,
            left: ‘40px‘,
            top: ‘40px‘,
            width: ‘100px‘,
            height: ‘100px‘,
            backgroundColor: ‘#f40‘
        }
        if(this.props.open){
            styles.display = ‘block‘;
        }else{
            styles.display = ‘none‘;
        }
        return (
            <div className="popup" style={styles}></div>
        )
    }
})
ReactDom.render(
    <App/>,
    document.getElementById(‘root‘)
);

第一个功能实现了,再来看第二个

点击弹窗让其消失

同样子级的显示与否掌控在父级手里

要向让子级消失,就必须要改变父级的组件状态this.state

所以我们必须要把事件函数绑定在父级

再利用组件属性this.props传递给子级

完整代码如下

var App = React.createClass({
    getInitialState: function(){
        return {
            open: false
        }
    },
    buttonHandler: function(){
        this.setState({
            open: true
        });
    },
    popupHandler: function(){
        this.setState({
            open: false
        });
    },
    render: function(){
        return (
            <div>
                <button onClick={this.buttonHandler}>点击</button>
                <PopUp open={this.state.open} handler={this.popupHandler}></PopUp>
            </div>
        )
    }
});
var PopUp = React.createClass({
    render: function(){
        var styles = {
            position: ‘absolute‘,
            left: ‘40px‘,
            top: ‘40px‘,
            width: ‘100px‘,
            height: ‘100px‘,
            backgroundColor: ‘#f40‘
        }
        if(this.props.open){
            styles.display = ‘block‘;
        }else{
            styles.display = ‘none‘;
        }
        return (
            <div className="popup" style={styles} onClick={this.props.handler}></div>
        )
    }
})
ReactDom.render(
    <App/>,
    document.getElementById(‘root‘)
);

用一句话来总结一下,就是数据都交给父级来管理

==主页传送门==

时间: 2024-08-08 05:20:51

客户端高性能组件化框架React简介、特点、环境搭建及常用语法的相关文章

client高性能组件化框架React简单介绍、特点、环境搭建及经常使用语法

[本文源址:http://blog.csdn.net/q1056843325/article/details/54729657 转载请加入该地址] 明天就是除夕了 预祝大家新春快乐 [ ]~( ̄▽ ̄)~* 天天饭局搞得我是身心疲惫= = 所以更新比較慢 今天想跟大家分享的就是这个大名鼎鼎的React框架 简单介绍 React是近两年非常流行的框架 流行到什么程度呢? 我看了一下Github上的数据 React达到了5w8+的star 在JavaScript中star排名第4 受欢迎程度可见一斑

Atlas-手淘组件化框架的前世今生和未来的路

今天手淘技术团队宣布正式开源它们的容器框架Atlas,项目地址: https://github.com/alibaba/atlas 同时他们还推出了项目官网,上线了技术文档: http://atlas.taobao.org/ 下面让Atlas团队来介绍下该项目的历史.原理和未来. Atlas是什么 Atlas是古希腊神话中的天神,是波士顿动力公司的机器人,借助搜索引擎,得以发现这个名词背后许许多多的含义.在手机淘宝,Atlas是一个扎根于Android客户端的一个组件化容器框架,相比神话中用手和

2015前端组件化框架之路(转)

https://github.com/xufei/blog/issues/19 1. 为什么组件化这么难做 Web应用的组件化是一个很复杂的话题. 在大型软件中,组件化是一种共识,它一方面提高了开发效率,另一方面降低了维护成本.但是在Web前端这个领域,并没有很通用的组件模式,因为缺少一个大家都能认同的实现方式,所以很多框架/库都实现了自己的组件化方式. 前端圈最热衷于造轮子了,没有哪个别的领域能出现这么混乱而欣欣向荣的景象.这一方面说明前端领域的创造力很旺盛,另一方面却说明了基础设施是不完善的

2015前端组件化框架之路

特别声明:本文转自@民工精髓的<2015前端组件化框架之路>.谢谢@民工精髓的分享!著作权归作者所有. 编辑推荐: 掘金是一个高质量的技术社区,从 CSS 到 Vue.js,性能优化到开源类库,让你不错过前端开发的每一个技术干货. 点击链接查看最新前端内容,或到各大应用市场搜索「 掘金」下载APP,技术干货尽在掌握中著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.原文: http://www.w3cplus.com/components-in-webapp.html ? w

【转】前端组件化框架之路

1. 为什么组件化这么难做 Web应用的组件化是一个很复杂的话题. 在大型软件中,组件化是一种共识,它一方面提高了开发效率,另一方面降低了维护成本.但是在Web前端这个领域,并没有很通用的组件模式,因为缺少一个大家都能认同的实现方式,所以很多框架/库都实现了自己的组件化方式. 前端圈最热衷于造轮子了,没有哪个别的领域能出现这么混乱而欣欣向荣的景象.这一方面说明前端领域的创造力很旺盛,另一方面却说明了基础设施是不完善的. 我曾经有过这么一个类比,说明某种编程技术及其生态发展的几个阶段: 最初的时候

Android组件化框架设计与实践

在目前移动互联网时代,每个 APP 就是流量入口,与过去 PC Web 浏览器时代不同的是,APP 的体验与迭代速度影响着用户的粘性,这同时也对从事移动开发人员提出更高要求,进而移动端框架也层出不穷. 上图显示的是传统的服务端架构和客户端 App 架构对比.传统的服务端架构中最底下是一个 OS,一般是 Linux,最上面服务端的业务,而中间有非常多的层次可以在架构上,按照我们的意愿搭建中间的各个层次的衔接环节,使得架构具有足够的灵活性和扩展性.但是到了 App 就会面对一个完全不同的现状,App

组件化和 React

一,对组件化的理解 1,组件的封装 -视图 -数据 -变化逻辑(数据驱动视图变化) 例: import React, { Component } from 'react'; import List from './list/index.js'; import Input from './input/index.js'; class Todo extends Component { constructor(props) { // 数据 super(props) this.state = {//保存

React+Webpack+ES6环境搭建(自定义框架)

引言 目前React前端框架是今年最火的.而基于React的React Native也迅速发展.React有其独特的组件化功能与JSX的新语法,帮助前端设计有了更好的设计与便捷,而React Native更是扩大了前端的边界. 说道React,那就不得不说一下Webpack凭借它异步加载和可分离打包等优秀的特性,走在取代Grunt和Gulp的路上.而面向未来的ES6,更是支持模块化处理. 下面我就分享一下关于Webpack+React+ES6的环境搭建(通用)[附加发布版] 准备工作 首先需要准

mac 下 react Native android环境搭建

1.参考  上一篇的博客文章 "mac 下 react Native ios环境搭建",前面几步都是必须的,只是,原生客户端不一致 2.Android Studio的安装 A:安装JAVA的SDK 注意:Android Studio需要Java Development Kit [JDK] 1.8或更高版本.你可以在命令行中输入 javac -version来查看你当前安装的JDK版本.如果版本不合要求,可以到 官网上下载 B:除非特别注明,请不要改动安装过程中的选项.比如Android