美文网首页
React 入门(阮一峰教程笔记)

React 入门(阮一峰教程笔记)

作者: 喂喂喂章鱼 | 来源:发表于2018-06-15 15:38 被阅读0次

    一 react.js react-dom.js Brower.js

    1. react.js 核心库
    2. react-dom.js提供dom方法
    3. Brower.js JSX语法--->JS语法
      服务器
      $ babel src --out-dir build //src内的js文件全部转换 放入build文件夹

    二 ReactDOM.render()

    ReactDOM.render(
      <h1>Hello, world!</h1>,
      document.getElementById('example')
    );
    

    三 JSX语法

    1. 支持js和html混写
    var names = ['Alice', 'Emily', 'Kate'];
    
    ReactDOM.render(
      <div>
      {
        names.map(function (name) {
          return <div>Hello, {name}!</div>
        })
      }
      </div>,
      document.getElementById('example')
    );
    
    1. < 与 {
      JSX 与 数组
    var arr = [
      <h1>Hello world!</h1>,
      <h2>React is awesome</h2>,
    ];
    ReactDOM.render(
      <div>{arr}</div>,
      document.getElementById('example')
    );
    
    # 四 组件
    ```javascipt
    var HelloMessage = React.createClass({
      render: function() {
        return <h1>Hello {this.props.name}</h1>;
      }
    });
    
    ReactDOM.render(
      <HelloMessage name="John" />,
      document.getElementById('example')
    );
    

    解释:

    1. 通过 React.createClass()方法构造组件类 HelloMessage,HelloMessage 是个类所以规范和类一样。组件类的第一个字母必须大写,否则会报错。
    2. 模版插入 <HelloMessage name="John" /> 的时候,就是在生成一个HelloMessage类的实例。
    3. 所有组件类必须拥有一个自己的render方法 用于输出组件。
    4. 组件类只能包含一个顶层标签
    5. 同原生HTML一样,组件可以加入自定义属性,如例子中的 name="John",然后通过组件类的this.props属性获取。
    6. 由于原生js的保留字,class属性要写成className for属性要写成htmlFor

    五 this.props.children属性

    this.props的属性和组件的属性基本是一一对应的,但是有一个例外就是this.props.children属性。它是在遍历组件的子节点

    var NodeList = React.createClass({
      render: function() {
        return <ul>
              React.Children.map(this.props.children,(child)=>{
                 return  <li>{child}</li>   //记住要return啊兄dei
    })
        </ul>;
      }
    });
    
    ReactDOM.render(
      <NodeList>
          <span>john</span>
          <span>sam</span>
      </NodeList>
      document.getElementById('example')
    );
    

    解释:

    1. this.props.children的值有三种可能 :一个孩子节点:对象;多个孩子节点:数组;没有孩子节点:undefined
    2. React.Children是一个React提供的工具函数,用来处理this.props.children 而不用太关心子节点的类型(这个map方法的用法需要理解记一下)
    3. React.Children还有一些别的方法 ,官方手册

    六 PropType

    1. 组件的属性可以接受字符串,数字,函数等任意类型,然而有时候我们想要规定组件能接受的类型,需要验证别人使用组件时的参数是否符合要求。
    var MyTitle = React.createClass({
      propTypes: {
        title: React.PropTypes.string.isRequired //要求类型时string
      },
    
      render: function() {
         return <h1> {this.props.title} </h1>;
       }
    });
    
    var data = 123;
    
    ReactDOM.render(
      <MyTitle title={data} />  //由于data是个数字不是要求的string类型 所以控制台会报错
      document.body
    

    留下PropType的官方文档

    1. 可以通过getDefaultProps设置默认属性
    var MyTitle = React.createClass({
      getDefaultProps : function () {
        return {
          title : 'Hello World'
        };
      },
    
      render: function() {
         return <h1> {this.props.title} </h1>;
       }
    });
    
    ReactDOM.render(
      <MyTitle />,
      document.body
    );
    

    七 获取真实的DOM节点

    1. diff算法:
      组件并不是真实的DOM节点,而是存在与内存中的一种数据结构,叫做虚拟DOM,只有当它真正插入文档中的时候才会真的变成DOM。
      React的设计时所有的DOM变动都现在虚拟的DOM上发生,然后再将实际变动的部分反映在真实的DOM上。这就是DOM diff 算法,它可以大大提升网页的性能表现。

    2. 如果想要拿到真实DOM,就要使用ref属性

    var MyComponent = React.createClass({
      handleClick: function() {
        this.refs.myTextInput.focus();
      },
      render: function() {
        return (
          <div>
            <input type="text" ref="myTextInput" />
            <input type="button" value="Focus the text input" onClick={this.handleClick} />
          </div>
        );
      }
    });
    
    ReactDOM.render(
      <MyComponent />,
      document.getElementById('example')
    );
    
    1. 由于虚拟DOM是不能拿到用户的输入,所以如果要拿到输入,文本框必须要有一个ref属性(上例中:ref="myTextInput"),然后this.refs.[refName]就会返回真实的节点(上例子中:this.refs.myTextInput)
    2. 注意:由于this.refs.[refName]获取的是真实的DOM,所以一定要等到虚拟DOM插入文档之后才能使用这个属性,否则会报错,上例中通过为组件制定Click事件的回调函数,使得只有在真正的DOM被click(意味着虚拟DOM已经转换成了真实的DOM)之后,才读取this.refs.[refName]获得真实的DOM

    this.state

    将组件看成一个状态机,有一个初始状态,然后随着用户的交互状态发生改变而重新渲染UI。

    var LikeButton = React.createClass({
      getInitialState: function() {
        return {liked: false};
      },
      handleClick: function(event) {
        this.setState({liked: !this.state.liked});
      },
      render: function() {
        var text = this.state.liked ? 'like' : 'haven\'t liked';
        return (
          <p onClick={this.handleClick}>
            You {text} this. Click to toggle.
          </p>
        );
      }
    });
    
    ReactDOM.render(
      <LikeButton />,
      document.getElementById('example')
    );
    
    1. LikeButton组件类的getInitialState方法(这个方法是自带的)设置一个状态的初始值,就是一个对象(本例中{like:false}),这个对象可以通过this.state读取。render渲染出组件。用户点击导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
      由于 this.props 和 this.state 都用于描述组件的特性,可能会产生混淆。一个简单的区分方法是,this.props 表示那些一旦定义,就不再改变的特性,而 this.state 是会随着用户互动而产生变化的特性。

    十 组件的生命周期

    1. 组件生命周期有三种:
      - Mounting: 已插入真实的DOM
      - Updating: 正在被重新渲染
      - Unmounting: 已移除真实DOM

    2. 每个状态都配有Will 和 Did相应的处理函数

      • componentWillMount()
      • componentDidMount()
      • componentWillUpdate(object nextProps, object nextState)
      • componentDidUpdate(object prevProps, object prevState)
      • componentWillUnmount()
    3. 两个特殊状态的处理函数

      • componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
      • shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用

    参考文档

    1. 例子
    var Hello = React.createClass({
      getInitialState: function () {
        return {
          opacity: 1.0
        };
      },
    
      componentDidMount: function () {
        this.timer = setInterval(function () {
          var opacity = this.state.opacity;
          opacity -= .05;
          if (opacity < 0.1) {
            opacity = 1.0;
          }
          this.setState({
            opacity: opacity
          });
        }.bind(this), 100);
      },
    
      render: function () {
        return (
          <div style={{opacity: this.state.opacity}}>
            Hello {this.props.name}
          </div>
        );
      }
    });
    
    ReactDOM.render(
      <Hello name="world"/>,
      document.body
    );
    

    上面代码在hello组件加载以后,通过 componentDidMount 方法设置一个定时器,每隔100毫秒,就重新设置组件的透明度,从而引发重新渲染
    注意,内联样式

    <div style={{opacity: this.state.opacity}}> //正确 外层大括号表示这是JS语法
    <div style={opacity: this.state.opacity}> //错误
    

    Ajax & Promise

    采用Promise抓取github上面最高点赞的项目的例子是个很好的promise加React应用的例子。

    var RepoList = React.createClass({
      getInitialState: function() {
        return { loading: true, error: null, data: null};
      },
    
      componentDidMount() {
        this.props.promise.then(
          value => this.setState({loading: false, data: value}),
          error => this.setState({loading: false, error: error}));
      },
    
      render: function() {
        if (this.state.loading) {
          return <span>Loading...</span>;
        }
        else if (this.state.error !== null) {
          return <span>Error: {this.state.error.message}</span>;
        }
        else {
          var repos = this.state.data.items;
          var repoList = repos.map(function (repo) {
            return (
              <li>
                <a href={repo.html_url}>{repo.name}</a> ({repo.stargazers_count} stars) <br/> {repo.description}
              </li>
            );
          });
          return (
            <main>
              <h1>Most Popular JavaScript Projects in Github</h1>
              <ol>{repoList}</ol>
            </main>
          );
        }
      }
    });
    

    相关文章

      网友评论

          本文标题:React 入门(阮一峰教程笔记)

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