美文网首页
03.React组件

03.React组件

作者: Ching_Lee | 来源:发表于2018-02-05 13:55 被阅读0次

    所有的demo源码:https://github.com/Ching-Lee/react-base

    1.概念

    组件就像JavaScript中的方法,他们接收一个参数props,表示属性,返回要显示在屏幕上的元素。
    注意:自定义的组件首字母必须大写。如果是小写,React会认为这是DOM的标签。

    2.定义组件

    demo03:

    <body>
       <div id="firstComponent"></div>
       <div id="secondComponent"></div>
       <script type="text/babel">
           //使用方法定义组件
           function Welcome(props) {
               return <h1>Hello,{props.name}</h1>
           }
    
           //使用类定义组件
           class Wel extends React.Component{
               render(){
                   return <h1>Hello,{this.props.name}</h1>
               }
           }
    
           ReactDOM.render(<Welcome name="用function定义的Welcome组件"/>,document.getElementById("firstComponent"));
           ReactDOM.render(<Wel name="用class定义的Wel组件"/>,document.getElementById("secondComponent"));
       </script>
    </body>      
    
    demo03

    3.组件可以使用其他组件构成

    function Welcome(props) {
      return <h1>Hello, {props.name}</h1>;
    }
    
    function App() {
      return (
        <div>
          <Welcome name="Sara" />
          <Welcome name="Cahal" />
          <Welcome name="Edite" />
        </div>
      );
    }
    
    ReactDOM.render(
      <App />,
      document.getElementById('root')
    );
    

    4.组件的生命周期

    组件的生命周期包括初始化、运行中、销毁三个阶段,每个阶段有相应的方法。

    • 初始化阶段
    • 运行中阶段
    • 销毁阶段

    示例:定时器
    1)只使用render完成:demo04

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>组件的生命周期</title>
        <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>
    <body>
    <script type="text/babel">
        class Clock extends React.Component {
            render() {
                return (
                        <div>
                            <h1>定时器使用render完成</h1>
                            <h2>It is {this.props.date.toLocaleTimeString()}.</h2>
                        </div>
                );
            }
        }
        function tick() {
            ReactDOM.render(<Clock date={new Date()}/>,document.body);
        }
    
        setInterval(tick,1000);
    
    </script>
    </body>
    </html>
    
    

    2)使用生命周期中相关函数完成
    demo05

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>state和生命周期</title>
        <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>
    <body>
        <script type="text/babel">
            class Clock extends React.Component{
                constructor(props){
                    super (props);
                    this.state={date:new Date()};
                }
                render(){
                    return(
                            <div>
                                <h1>生命周期和state</h1>
                                <h2>It is {this.state.date.toLocaleTimeString()}</h2>
                            </div>
                    );
                }
                tick(){
                    this.setState({date:new Date()});
                }
                //在初始阶段渲染完成后,设置state值,获取实时时间
                componentDidMount(){
                       this.intervalId=setInterval(()=>this.tick(),1000);
                }
    
                //在销毁阶段
                componentWillUnmount(){
                    clearInterval(this.intervalId);
                }
    
            }
    
            ReactDOM.render(<Clock/>,document.body);
        </script>
    </body>
    </html>
    

    5. props和state 详解

    5.1 属性

    组件的props属性的值有类型限制

    import PropTypes from 'prop-types';
    组件名.propTypes={
    //传递的userid属性值必须是number类型
      userid:Proptypes.number,
     //如果这个属性值是必须的,调用该组件的时候必须要传递这个值
    userid:Proptypes.number.isRequired
    };
    

    组件中可以定义默认的属性值

    组件名.defaultProps=自己定义的属性对象。
    
    5.2 状态state
    • 状态的含义
      state:在组件中可以改变
    • 状态的用法
      getInitialState:初始化每个实例的特有状态
      setState:更新组件状态
    this.setState({comment: 'Hello'});
    

    注意:props和state的更新是异步的,你不能依赖他们的值去计算下一个state。

    // Wrong
    this.setState({
      counter: this.state.counter + this.props.increment,
    });
    //为了解决上述问题,使用如下形式的setState(),它接收的参数是函数,而不是对象,将之前的state作为第一个参数,属性作为第二个参数。
    
    // Correct
    this.setState(function(prevState, props) {
      return {
        counter: prevState.counter + props.increment
      };
    });
    //使用箭头函数
    // Correct
    this.setState((prevState, props) => ({
      counter: prevState.counter + props.increment
    }));
    

    setState发生之后会触发diff算法,diff算法会判断state变化之后的结果和目前页面上结果有什么区别,如果没有区别,则页面不需要更新。如果页面有区别,则找出不同的地方并更新特定的位置的DOM。

    5.3 属性和状态的对比
    • 相似点
      1)都是纯Js对象
      2)都会触发render更新
      3)都具有确定性
    5.4 属性和状态实战

    实现一个评论框:demo06

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
        <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
        <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    </head>
    <body>
    <script type="text/babel">
        class Content extends React.Component {
            constructor(props){
                super(props);
            }
            render() {
                return <p>{this.props.selectName}</p>;
            }
        }
    
    
        class Comment extends React.Component {
           constructor(props){
               super(props);
               this.state={names:["Tim","John","Hank"],selectName:''};
           }
            //当select发生改变时,设置state的selectName的值
           handleSelect(event){
               this.setState({selectName:event.target.value});
           }
            render() {
                let options=[];
                for(let option in this.state.names){
                    options.push(<option value={this.state.names[option]}>{this.state.names[option]}</option>);
                }
                //注意,这里必须使用箭头函数,需要将 handleSelect方法中的this作用域在定义时指定为组件(也就是类)
                return (
                    <div>
                        <select onChange={(event)=>this.handleSelect(event)}>
                            {options}
                        </select>
                        <Content selectName={this.state.selectName}/>
                    </div>
    
                );
            }
        }
    
        ReactDOM.render(<Comment/>,document.body);
    </script>
    
    </body>
    </html>
    

    6.组件的refs

    我们有的时候也需要获取原生的html元素结点

    //方式1
    let button=document.getElementById('submitButton');
    ReactDOM.findDOMNode(button).style.color='red';
    //方式2
    可以给元素添加refs属性,直接获取
    <button refs="submitButton">提交</button>
    this.refs.submitButton.style.color='red';
    

    7.独立组件间共享Mixins

    安装mixin的包

    sudo npm install --save react-mixin
    

    mixin.js

    //定义了一个 MixinLog对象
    const MixinLog={
    log(){
      console.log("abcdefg...")
     }
    };
    export default MixinLog
    

    其他js文件中调用

    import ReactMixin from 'react-mixin'
    import MixinLog from './mixins';
    ReactMixin(类名.prototype,Mixinlog)
    //可以直接使用Mixinlog对象
    Mixinlog.log();
    

    相关文章

      网友评论

          本文标题:03.React组件

          本文链接:https://www.haomeiwen.com/subject/hqexzxtx.html