zoukankan      html  css  js  c++  java
  • [react002] component基本用法

    1 什么是component

    设计接口的时候,把通用的设计元素(按钮,表单框,布局组件等)拆成接口良好定义的可复用的组件。 这样,下次开发相同界面程序时就可以写更少的代码,也意义着更高的开发效率,更少的 Bug 和更少的程序体积。 Thinking in react 里面举了一个React 构建可搜索的商品数据的例子。

    接下来我们将创建一个好玩的component来全面了解它的组成和运行机制, 回顾一下我们在 001 中的 public/index.html 它是直接引用了webpack生成的client.min.js(console里面打印文字)。 这样一点都不好玩,接来下我们从头开始构造一个完成的index.hmtl页面.

    2. 定义html和引用的js入口

    <html>
      <head>
        <meta charset="utf-8">
        <title>React's Component Example</title>
      </head>
      <body>
          <div id="app"></div>
        <script src="client.min.js" type="text/javascript"></script>
      </body>
    </html>

     在html里面定义一个id= "app" 的 div标签并引用client.min.js,这个html就是我们的入口。 时刻记得client.min.js是来自于webpack的entry: src/client.js 里面生成的。 所以我们就通过client.js来操作html中的div构建页面。

    import React from 'react';
    import ReactDom from "react-dom";
    import Layout from "./component/Layout";
    const app = document.getElementById("app");
    ReactDom.render(<Layout />, app);
     看懂上面的语法你应该要学会的是基本的JSX语法, 看完后问自己2个问题:
    1. 为什么要使用JSX语法?
    2. JSX和HTML的差异是什么?

    这里你只需要知道 <Layout /> 是引用Layout Component。

    页面的构成应该是(页面就是一个Tree,不要什么都堆在一起)

    –Layout 
      -—Header 
           –title 
       -—Body 
       -—Footer

    2.1. 定义最上层的Layout

    import React from 'react';
    import Footer from "./Footer";
    import Header from "./Header";
    
    export default class Layout extends React.Component {
        render() {
            return (<div>
                    <Header />
                    <Footer />
                    </div>);
        };
    }

     component 必须要定义的render函数,render是核心, 它组装生成这个组件的HTML结构(使用原生HTML标签或者子组件)。

    当调用的时候,会检测 this.props 和 this.state,返回一个单子级组件(注意只能是单个,所以我们用div把header和footer包了一层)。

    该子级组件可以是虚拟的本地 DOM 组件(比如 <div /> 或者 React.DOM.div()),也可以是自定义的复合组件。

    你也可以返回 null 或者 false 来表明不需要渲染任何东西。 实际上,react 渲染一个 <noscript> 标签来处理当前的差异检查逻辑。当返回 null 或者 false 的时候,this.getDOMNode() 将返回 null。

    render() 函数应该是纯粹的,也就是说该函数不修改组件state, 每次调用都返回相同的结果,不读写 DOM 信息,也不和浏览器交互(例如通过使用setTimeout)。 如果需要和浏览器交互,在 componentDidMount() 中或者其它生命周期方法中做这件事。保持 render() 纯粹,可以使服务器端渲染更加切实可行,也使组件更容易被理解。

    2.2. 定义Footer

    import React from "react";
    export default class Footer extends React.Component {
        render() { return(<div> <h3> Footer: Building UI is a funny thing </h3> </div>);}
    }

    只是简单的把自己用h1显示出来

    2.3. 定义Header

    import React from "react";
    import Title from "./Title";
    export default class Header extends React.Component {
        render() {
            return(<div>
                   <Title />
                   <h3> Header: Component create a new world </h3>
                   </div> );
        }
    }

    我们就可以看到它引用了Title

    2.4. 定义Title

    import React from "react";
    export default class Title extends React.Component {
        render() {
            return(<div>
                    <h2> Title: Everything is Component  </h2>
                    </div>
            );
        }
    }

    这上面都是静态的东西,根本就看不出component有什么值得炫酷的地方,只是显示了 title header footer。 离标题Title随着我们给定的输入框的文字变化还差得远 不过在开始之前, 应该先预习一下component api弄明白它的state和prop。

    1. props就是component的属性,由外部通过JSX属性传入设置,一旦初始设置完成,就可以认为this.props是不可更改的,

    所以不要轻易更改设置this.props里面的值(虽然对于一个JS对象你可以做任何事)。

    2. state是component的当前状态,可以把component简单看成一个“状态机”,根据状态state 呈现不同的UI展示。

    一旦状态(数据)更改,component就会自动调用render重新渲染UI,这个更改的动作会通过 this.setState方法来触发。

    3. 一条原则:让component尽可能地少状态。这样组件逻辑就越容易维护。当更改这个状态(数据)需要更新组件UI的就可以认为是state

    4. 无状态compoent, 我们上面的4个就是这种无状态的。

    你也可以用纯粹的函数来定义无状态的组件(stateless function), 这种组件没有状态,没有生命周期,只是简单的接受props 渲染生成DOM 结构。无状态组件非常简单,开销很低,如果可能的话尽量使用无状态组件。

    3. 有状态的component

    我们要做的就是Layout把要改变的title和改变title的函数一级一级的传给下级的component 这必须要用到component间是怎么通信的

     3.1 父子间通信就是通过props属性来传递, 在父component中给子component设置props,然后子component就可以访问到父component的数据和方法.

    3.2 非父子间通信使用全局事件Pub/Sub模式,在componentDidMount里面订阅事件,在 componentWillUnmount里面取消订阅,当收到事件触发的时候调用setState更新UI。

    这里我们只用到了父子间通信。

    在Layout中把title和changetitle的函数都传给header component, 注意传给下一级方法时一定要显示的表明这个方法来自己于哪里 — bind(this)操作。

    import React from 'react';
    import Footer from "./Footer";
    import Header from "./Header";
    
    export default class Layout extends React.Component {
        constructor(){
            super();
            this.state = {title: "welcome"};
        }
        changeTitle(title){
            this.setState({title: title});
        }
        render() {
            return (<div>
                    <Header changeTitle={this.changeTitle.bina(this)} title={this.state.title}/>
                    <Footer />
                    </div>);
        };
    }

    Header接收到这个Title后如何处理

    import React from "react";
    import Title from "./Title";
    export default class Header extends React.Component {
        handleChange(e) {
            const title = e.target.value;
            this.props.changeTitle(title);
        }
        render() {
            return(<div>
                   <Title title={this.props.title}/>
                   <input value={this.props.title} onChange= {this.handleChange.bind(this)}/> 
                   <input value={this.props.title} onChange= {this.handleChange.bind(this)}/> 
                   </div> );
        }
    }

    Header把title又往下传递给应该处理的Title Component, 自己又建了两个输入框,初始值为title,然后再定义一个onChange事件

    Title接到title后只需要把它显示成title就行了,这就是它要做的事!

    import React from "react";
    export default class Title extends React.Component {
        render() {
            return(<div>
                   <h2> {this.props.title}  </h2>
                    </div>
            );
        }
    }

    总结上面的流程就是Layout把自己changeTitle的方法和title的属性先传给Header,Header再把他们传给Title。

    这里发生了一件非常奇妙的事,我们在Layout Header Title 里都有state, 我们通过input输入框输入文字触发Layout的SetState方法, 结果所有的State里面的title都跟着变化啦,这就是virtual DOM的好处,react把操作真实DOM的操作又封装了一层,让我们不用操心哪一个DOM应该更新这种事。 JS很快,慢的只是刷新DOM里面的tree, 而且繁锁, 但是react把刷新DOM的操作透明了,简直太贴心啦。

     我们打开chrome developer tool 里面timeline的 Rendering下的Enable paint flashing,看看我们在输入的时候是哪一些DOM刷新啦。 

     

    可以看出它只是刷新应该刷新的Title Header和input

    通过这一章节我们掌握到了什么是component, component的state props及他们之前的区别,父子component之间如何通信。

    4 扩展阅读

  • 相关阅读:
    HDU 1874 畅通工程续(dijkstra)
    HDU 2112 HDU Today (map函数,dijkstra最短路径)
    HDU 2680 Choose the best route(dijkstra)
    HDU 2066 一个人的旅行(最短路径,dijkstra)
    关于测评机,编译器,我有些话想说
    测评机的优化问题 时间控制
    CF Round410 D. Mike and distribution
    数字三角形2 (取模)
    CF Round410 C. Mike and gcd problem
    CF Round 423 D. High Load 星图(最优最简构建)
  • 原文地址:https://www.cnblogs.com/zhongwencool/p/react_component.html
Copyright © 2011-2022 走看看