用HTML5和React Native分别实现盒子模型显示

写发不一样:

1、样式

HTML5

.a{
    position:absoule;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background-color:#fbfbfb;
}

React Native

a: {
    position: absoule,
    top: 0,
    left: 0,
    right: 0,
    bottom: 0,
    backgroundColor: #f9f9f9,
},

2、元素

HTML5

<span class="label">
    margin
</span>

React Native

<View style={[BoxStyles.label]}>
   <Text style={BoxStyles.white}>margin</Text> 
</View>


const BoxStyles = StyleSheet.create({
    label: {
      backgroundColor:white,  
    },
})

3、书写格式

JSX

React是由ReactJs与React Native组成,其中ReactJs是Facebook开源的一个前端框架,React Native是ReactJs思想在native上的体现

JSX不是一门新的语言,仅仅是个语法糖,允许开发者在JavaScript中书写HTML语法。最后每个HTML标签都转化为JavaScript代码来运行

1、环境    react.js   react-dom.js    browser.min.js

2、载入方式   外联、内联

3、标签   HTML标签   与    ReactJs创建的组件类标签(首字母一定要大写,驼峰命名)

4、转换   解析器

      <h3>输入</h3>    转换成

      React.createElement("h3",null,"输入")

5、执行JavaScript表达式

var msg = "helloWorld"

<h1>{msg}</h1>

React.createElement("h1",null,msg)

6、注释

单行://   多行:/*注释文本*/

7、属性

var msg = <h1 width="10px">helloWorld</h1>

React.createElement("h1",{width: "10px"},"helloWorld")

8、延展属性

使用ES6的语法

var props = {};
props.foo = "1";
props.bar = "1";

<h1 {...props}  foo="2">helloWorld</h1>

转换成

React.createElement("h1",React._spread({},props,{foo: "2"}),"helloWorld")

9、自定义属性(HTML5:凡是以data-开头的属性,可渲染到页面)

10、显示HTML  显示HTML的字符串,而不是HTML的节点

借助一个属性  _html

<div>{{_html:'<h1>HelloWorld</h1>'}}</div>     会解析成字符串的方式

11、样式的使用

style属性    js对象

<h1 style={{color: '#fbfbfb',fontSize: '24px'}}>ddd</h1>

外层{}是JSX语法   内层{}是JavaScript对象

12、事件绑定

驼峰命名 onClick

function test(msg){
    alert(msg)
}

var app =<button onClick={test.bind(this,'helloWorld')} style={{width:'200px',height:'200px'}}>点击</button>

React.render(app,document.getElementById('example'))

调用bind方法(设定作用域,要传递的参数)

React

ReactJS核心思想是组件化    多个组件组成了一个ReactJS应用

React是全局对象   顶层API与组件API

React.createClass创建组件类的方法

React.render渲染,将指定组件渲染到指定DOM节点

render:组件API,返回组件的内部结构

React.render被ReactDOM.render替代

ReactJS组件生命周期

1、创建阶段

getDefaultProps:处理props的默认值  在React.createClass调用

2、实例化阶段

getInitialState

  • componentWillMount:

在组件挂载到DOM前调用,且只会被调用一次,在这边调用this.setState不会引起组件重新渲染,也可以把写在这边的内容提前到constructor()中,所以项目中很少用。

  • render:

根据组件的props和state(无两者的重传递和重赋值,论值是否有变化,都可以引起组件重新render) ,return 一个React元素(描述组件,即UI),不负责组件实际渲染工作,之后由React自身根据此元素去渲染出页面DOM。render是纯函数(Pure function:函数的返回结果只依赖于它的参数;函数执行过程里面没有副作用),不能在里面执行this.setState,会有改变组件状态的副作用。

  • componentDidMount:

组件挂载到DOM后调用,且只会被调用一次

state:组件的属性,主要是用来存储组件自身需要的数据。每次数据的更新都是通过修改state属性的值。ReactJS内部会监听state属性变化,一旦发生变化就会主动触发组件的render方法来更新虚拟DOM结构

虚拟DOM:将真实的DOM结构映射成一个JSON数据结构

3、更新阶段

componentWillReceiveProps,shouldComponentUpdate,componentWillUpdate,render,componentDidUpdate

  • componentWillReceiveProps(nextProps)

此方法只调用于props引起的组件更新过程中,参数nextProps是父组件传给当前组件的新props。但父组件render方法的调用不能保证重传给当前组件的props是有变化的,所以在此方法中根据nextProps和this.props来查明重传的props是否改变,以及如果改变了要执行啥,比如根据新的props调用this.setState出发当前组件的重新render

  • shouldComponentUpdate(nextProps, nextState)

此方法通过比较nextProps,nextState及当前组件的this.props,this.state,返回true时当前组件将继续执行更新过程,返回false则当前组件更新停止,以此可用来减少组件的不必要渲染,优化组件性能。

ps:这边也可以看出,就算componentWillReceiveProps()中执行了this.setState,更新了state,但在render前(如shouldComponentUpdate,componentWillUpdate),this.state依然指向更新前的state,不然nextState及当前组件的this.state的对比就一直是true了。

  • componentWillUpdate(nextProps, nextState)

此方法在调用render方法前执行,在这边可执行一些组件更新发生前的工作,一般较少用。

  • render

render方法在上文讲过,这边只是重新调用。

  • componentDidUpdate(prevProps, prevState)

此方法在组件更新后被调用,可以操作组件更新的DOM,prevProps和prevState这两个参数指的是组件更新前的props和state

4、销毁阶段

  • componentWillUnmount

此方法在组件被卸载前调用,可以在这里执行一些清理工作,比如清楚组件中使用的定时器,清楚componentDidMount中手动创建的DOM元素等,以避免引起内存泄漏。

ReactJS组件通信

var Parent = React.createClass({
    click: function(){
        this.refs.child.getDOMNode().style.color = "red";
    },
    render: function(){
        return(
            <div onClick={this.click}></div>Parent Is
            <Child name={this.props.name} ref="child"></Child>
        )
    }
})

var Child = React.createClass({
    render: function(){
        return (
            <span>{this.props.name}</span>
        )
    }

})

ReactDOM.render(<Parent name="helloWorld" />,document.getElementById('example'));

子组件调用父组件

this.props

父组件调用子组件

首先用属性ref给子组件取个名字

this.refs.名字.getDOMNode().

样式

外联样式:style={styles.container}

内联样式:style={{flex:1,borderWidth:1}}

多个样式:style={[styles.contianer,styles.flex,{flex:1,borderWidth:1}]}

单独封装 独立成一个文件

module.exports = 组件名;

const Header = require('./文件名路径')

Navigator点击跳转传参

class HelloWorld extends React.Component{
    render(){
        let defaultName = 'List';
        let defaultComponent = List;
        return(
            <Navigator
                initialRouter = {{ name: defaultName,component: defaultComponent}}
                //配置场景
                configureScene = {()=>{
                        //这个是页面跳转时候的动画
                        return Navigator.SceneConfigs.VerticalDownSwipeJump;                        
                    }
                   
                }                
                renderScene = {(route,navigator)=>{
                        let Component = route.component;
                        return <Component {...route.params} navigator={navigator} />
                    }
                }
                />
        )
    }

}


class List extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            id: 1,
            user: null
        };
    }
    _pressButton(){
        const {navigator} = this.props;
        //为什么这里可以取得props.navigator
        //<Component {...route.params} navigator={navigator} />
        //这里传递了navigator作为props
        let that = this;
        if(navigator){
            navigator.push({
                name: 'Detail',
                component: Deatail,
                params: {
                    id: this.state.id,
                    //从详情页获取user
                    getUser: function(user){
                        that.setState({
                            user: user
                        })
                    }
                }
            })
        }
    }
    render(){
        if(this.state.user){
            return(
                <View>
                    <Text>用户信息:{JSON.stringify(this,state.user)}</Text>
                </View>
            )
        }else{
            return(
                <ScrollView style={styles.flex}>
                    <Text onPress={this._pressButton.bind(this)}>点击一下</Text>
                </ScrollView>
            )
        }
    }
}

const USER_MODELS = {
    1: {name:'mot',age: 23},
    2: {name:'晴明',age: 25}
};


class Detail extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            id: null
        };
    }
    componentDidMount(){
        //这里获取从List传递的参数id
        this.setState({
            id: this.props.id
        })
    }

    _pressButton(){
        const {navigator} = this.props;
        if(this.props.getUser){
            let user = USER_MODELS[this.props.id];
            this.props.getUser(user);
        }
        if(navigator){
            //出栈入栈,把当前的页面pop掉,这里就返回上一个页面了
            navigator.pop();
        }
    }
    render(){
        return(
            <ScrollView>
                <Text>传递过来的用户id是:{this.state.id}</Text>
                <Text onPress={this._pressButton.bind(this)}>点击我可以跳回去了</Text>
            </ScrollView>
        )
    }
}

 

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐