34.React学习笔记(JSX语法、组件、this.props.children、PropTypes、this.state、组件的生命周期、ajax)

一、HTML模板

使用react的源码大致是这样:

<!DOCTYPE html>
<html>
  <head>
    <script src="../build/react.js"></script>
    <script src="../build/react-dom.js"></script>
    <script src="../build/browser.min.js"></script>
  </head>
  <body>
    <div id="app"></div>
    <script type="text/babel">
      // ** Our code goes here! **
    </script>
  </body>
</html>

上边代码有两个地方需要注意:

(1)最后一个script标签的type属性为type/babel(因为react独有的JSX语法与JavaScript不兼容)

(2)上边使用了三个库,一定要首先加载:react.js是react的核心库;react-dom.js提供与DOM相关的功能;Browser.js将JSX语法转为JavaScript语法

二、ReactDom.render( )

用于将模板转为HTML语言,并插入指定的DOM节点:

ReactDom.rendeer(
    <h1>Hello,World!</h1>
    document.getElementById('app')
);

三、JSX语法

HTML语言直接写在JavaScript语言中,不加任何引号,就是JSX语法(它允许HTML和JavaScript的混写)

var names = ['Alice', 'Emily', 'Kate'];
ReactDOM.render(
  <div>
  {
    names.map(function (name) {
      return <div>Hello, {name}!</div>
    })
  }
  </div>,
  document.getElementById('example')
);

四、组件

react允许将代码封装成组件,React.createClass()方法用于生成一个组件类

var HelloMessage = React.createClass({
  render: function() {
    return <h1>Hello {this.props.name}</h1>;
  }
});

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

所有组件类都必须有render方法,用于输出组件;组件类的第一个字母必须大写,组件类只能包含一个顶层标签,否则都会报错

<HelloMessage name="lyf"/>:组件的name属性可以在组件类的this.props对象上获取

注:class属性要写成className,for要写成htmlFor

五、this.props.children

它表示组件的所有子节点:

ar NotesList = React.createClass({
  render: function() {
    return (
      <ol>
      {
        React.Children.map(this.props.children, function (child) {
          return <li>{child}</li>;
        })
      }
      </ol>
    );
  }
});
ReactDOM.render(
  <NotesList>
    <span>hello</span>
    <span>world</span>
  </NotesList>,
  document.body
);

上边NoteList组件有两个span子节点,都可以通过this.props.children获取。

注:this.props.children的值有三种可能:

(1)如果当前组件没有子节点,就是undefined

(2)如果有一个子节点,数据类型是object

(3)如果有多个子节点,数据类型是array

我们可以通过React.Children.map遍历子节点,就不用担心数据类型了

六、PropTypes

用来验证组件实例的属性是否符合要求

var MyTitle = React.createClass({
  propTypes: {
    title: React.PropTypes.string.isRequired,
  },

  render: function() {
     return <h1> {this.props.title} </h1>;
   }
});

上边Mytitle组件有一个title属性,PropTypes告诉react,title是必须的,并且是字符串,如果气门设置title为数值:

var data = 123;

ReactDOM.render(
  <MyTitle title={data} />,
  document.body
);

此时,属性title就通不过验证了

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节点

组件并不是真实的DOM节点,而是虚拟DOM,从组件获取真实的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')
);

上边代码中,MyComponent组件有一个文本输入框,用来获取用户的输入,文本框有一个ref属性,通过this.refs.[refName]就会返回这个真实的DOM节点

八、this.state

react将组件看成一个状态机,一开始有一个初始状态,然后用户互动,导致状态变化,从而触发重新渲染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')
);

上边代码中LikeButton组件的getInitialState方法用于定义初始状态,返回一个对象,可以通过this.state读取;当用户点击时,this.setState方法就会修改状态值,每次修改以后,自动调用this.render方法,再次渲染组件。

注:this.props和this.state都用于描述组件的特性,区别在于:this.props表示那些一旦定义,就不再改变的特性;this.state表示那些会随着用户互动而产生变化的特性。

九、表单

用户在表单填入的内容,属于用户跟组件的互动,不能用this.props读取

var Input = React.createClass({
  getInitialState: function() {
    return {value: 'Hello!'};
  },
  handleChange: function(event) {
    this.setState({value: event.target.value});
  },
  render: function () {
    var value = this.state.value;
    return (
      <div>
        <input type="text" value={value} onChange={this.handleChange} />
        <p>{value}</p>
      </div>
    );
  }
});

ReactDOM.render(<Input/>, document.body);

上边代码中,文本框的值value不能用this.props.value读取,需要定义一个onChange事件,通过event.target.value读取用户输入的值

十、组件的生命周期

1.组件的生命周期分为三个状态:

(1)Mounting:已插入真实DOM 

(2)Updating:正在被重新渲染

(3)Unmounting:已移出真实DOM

2.每个状态有两种处理函数:

will函数在进入状态之前调用,did函数在进入状态之后调用,三种状态共计五种处理函数:

(1)componentWillMount()

(2)componentDidMount()

(3)componentWillUpdate(object nextProps,object nextState)

(4)componentDidUpdate(object prevProps,object prevState)

(5)componentWillUnmount

3.react还提供两种特殊的处理函数:

(1)componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用

(2)shouldComponentUpdate(object nextProps,object nextState):组件判断是否重新渲染时调用

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毫秒就重新设置组件的透明度,从而引发重新渲染;组件的style属性设置方式:style= {{opacity:this.state.opacity}},这是因为react组件样式是一个对象,第一层花括号表示这是JavaScript语法,第二层表示样式对象。

十一、ajax

组件的数据来源通常是通过ajax请求从服务器获取,可以使用componentDidMount方法设置ajax请求,等请求成功,再用this.setState方法重新渲染UI:

var UserGist = React.createClass({
  getInitialState: function() {
    return {
      username: '',
      lastGistUrl: ''
    };
  },

  componentDidMount: function() {
    $.get(this.props.source, function(result) {
      var lastGist = result[0];
      if (this.isMounted()) {
        this.setState({
          username: lastGist.owner.login,
          lastGistUrl: lastGist.html_url
        });
      }
    }.bind(this));
  },

  render: function() {
    return (
      <div>
        {this.state.username}'s last gist is
        <a href={this.state.lastGistUrl}>here</a>.
      </div>
    );
  }
});
ReactDOM.render(
  <UserGist source="https://api.github.com/users/octocat/gists" />,
  document.body
);

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值