React学习2

ReactDOM.render

ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。

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

上面代码将一个 h1 标题,插入 example 节点

React JSX

React 使用 JSX 来替代常规的 JavaScript。
JSX的优点:

  • JSX 执行更快,因为它在编译为 JavaScript 代码后进行了优化。
  • 它是类型安全的,在编译过程中就能发现错误。
  • 使用 JSX 编写模板更加简单快速。

JavaScript 表达式

在 JSX 中使用 JavaScript 表达式。表达式要写在花括号 {} 中。实例如下:

ReactDOM.render(
    <div>
      <h1>{1+1}</h1>
    </div>
    ,
    document.getElementById('example')
);

在 JSX 中不能使用 if-else 语句,但可以使用三元运算表达式来替代。示例如下:

ReactDOM.render(
    <div>
      <h1>{i == 1 ? 'True' : 'False'}</h1>
    </div>
    ,
    document.getElementById('example')
);

样式

React 推荐使用内联样式,React 会在指定元素数字后自动添加 px 。示例如下:

var myStyle = {
    fontSize: 30,
    color: '#FF0000'
};
ReactDOM.render(
    <h1 style = {myStyle}>Hello World</h1>,
    document.getElementById('example')
);

注释

注释需要写在花括号中,实例如下:

ReactDOM.render(
    <div>
    <h1>React学习</h1>
    {/*注释...*/}
    </div>,
    document.getElementById('example')
);

数组

JSX 允许在模板中插入数组,数组会自动展开所有成员:

var arr = [
  <h1>Hello React</h1>,
  <h2>Hello React Native</h2>,
];
ReactDOM.render(
  <div>{arr}</div>,
  document.getElementById('example')
);

HTML 标签 vs React 组件

React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。

  • 要渲染 HTML 标签,只需在 JSX 里使用小写字母的标签名。
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
  • 要渲染 React 组件,只需创建一个大写字母开头的本地变量。
var MyComponent = React.createClass({/*...*/});
var myElement = <MyComponent someProperty={true} />;
ReactDOM.render(myElement, document.getElementById('example'));

React 的 JSX 使用大、小写的约定来区分本地组件的类和 HTML 标签。
注意:
由于 JSX 就是 JavaScript,一些标识符像 class 和 for 不建议作为 XML 属性名。作为替代,React DOM 使用 className 和 htmlFor 来做对应的属性。

React 组件

Demo:

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

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

这里使用React.createClass 方法用于生成一个组件类 HelloMessage。
实例组件类并输出信息。
如果需要向组件传递参数,可以使用 this.props 对象
注意:

  • 原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 HelloMessage 不能写成 helloMessage。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
  • 在添加属性时, class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。

React State(状态)

React 把组件看成是一个状态机(State Machines)。通过与用户的交互,实现不同状态,然后渲染 UI,让用户界面和数据保持一致。
React 里,只需更新组件的 state,然后根据新的 state 重新渲染用户界面(不要操作 DOM)。
以下Demo中创建了 LikeButton 组件,getInitialState 方法用于定义初始状态,也就是一个对象,这个对象可以通过 this.state 属性读取。当用户点击组件,导致状态变化,this.setState 方法就修改状态值,每次修改以后,自动调用 this.render 方法,再次渲染组件。
Demo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>react state</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../build/react.js"></script>
    <script type="text/javascript" src="../build/react-dom.js"></script>
    <script type="text/javascript" src="../build/browser.min.js"></script>
    <script type="text/babel"> var LikeButton = React.createClass({ getInitialState:function(){ return {liked:true}; }, handleClick:function(event){ this.setState({liked:!this.state.liked}); }, render:function(){ var text = this.state.liked ? '喜欢':'不喜欢'; return ( <p onClick = {this.handleClick}>You {text} this(点击切换状态)</p> ); } }); ReactDOM.render( <LikeButton/>, document.getElementById("example") ); </script>
</body>
</html>

React Props

state 和 props 主要的区别在于 props 是不可变的,而 state 可以根据与用户交互来改变。这就是为什么有些容器组件需要定义 state 来更新和修改数据。
Demo:
这个小例子组合使用了 state 和 props 。在父组件中设置了 state, 并通过在子组件上使用 props 将其传递到子组件上。在 render 函数中, 我们设置 name 和 site 来获取父组件传递过来的数据。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>state和props</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../build/react.js"></script>
    <script type="text/javascript" src="../build/react-dom.js"></script>
    <script type="text/javascript" src="../build/browser.min.js"></script>
    <script type="text/babel"> var Websites = React.createClass({ getInitialState:function(){ return { name:"百度一下", site:"http://www.baidu.com" }; }, render:function(){ return ( <div> <Name name = {this.state.name}/> <Link site = {this.state.site}/> </div> ); } }); var Name = React.createClass({ render:function(){ return ( <h1>{this.props.name}</h1> ); } }); var Link =React.createClass({ render:function(){ return( <a href = {this.props.site}>{this.props.site}</a> ); } }); ReactDOM.render( <Websites />, document.getElementById("example") ); </script>
</body>
</html>

React 组件生命周期

组件的生命周期可分成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

React 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数:

  • componentWillMount() 在渲染前调用,在客户端也在服务端。
  • componentDidMount() 在第一次渲染后调用,只在客户端。
  • componentWillUpdate() 在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用
  • componentDidUpdate() 在组件完成更新后立即调用。在初始化时不会被调用。
  • componentWillUnmount() 在组件从 DOM 中移除的时候立刻被调用。

React 的两种特殊状态的处理函数:

  • componentWillReceiveProps():已加载组件收到新的参数时调用
  • shouldComponentUpdate():返回一个布尔值。在组件接收到新的props或者state时被调用,判断是否重新渲染组件,可以在你确认不需要更新组件时可以将其设为false。
    Demo:
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>组件生命周期</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../build/react.js"></script>
    <script type="text/javascript" src="../build/react-dom.js"></script>
    <script type="text/javascript" src="../build/browser.min.js"></script>
    <script type="text/babel"> var Button = React.createClass({ getInitialState:function(){ return { data:0 }; }, setNumber:function(){ this.setState({ data:this.state.data+1 }); }, render:function(){ return ( <div> <button onClick = {this.setNumber}>增加</button> <Content myNumber = {this.state.data}/> </div> ); } }) var Content = React.createClass({ componentWillMount:function() { console.log('Component WILL MOUNT!') }, componentDidMount:function() { console.log('Component DID MOUNT!') }, componentWillReceiveProps:function(newProps) { console.log('Component WILL RECIEVE PROPS!') }, shouldComponentUpdate:function(newProps, newState) { return true; }, componentWillUpdate:function(nextProps, nextState) { console.log('Component WILL UPDATE!'); }, componentDidUpdate:function(prevProps, prevState) { console.log('Component DID UPDATE!') }, componentWillUnmount:function() { console.log('Component WILL UNMOUNT!') }, render:function(){ return ( <div> <h1>{this.props.myNumber}</h1> </div> ); } }); ReactDOM.render( <Button />, document.getElementById("example") ); </script>
</body>
</html>

React AJAX

React 组件的数据可以通过 componentDidMount 方法中的 Ajax 来获取,当从服务端获取数据库可以将数据存储在 state 中,再用 this.setState 方法重新渲染 UI。
当使用异步加载数据时,在组件卸载前使用 componentWillUnmount 来取消未完成的请求。
Demo:
获取 Github 用户最新 gist 共享描述

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>reactAjax</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="build/react.js"></script>
    <script type="text/javascript" src="build/react-dom.js"></script>
    <script type="text/javascript" src="build/browser.min.js"></script>
    <script type="text/javascript" src="build/jquery.min.js"></script>
    <script type="text/babel"> var UserGist = React.createClass({ getInitialState:function(){ return { username:'', lastGistUrl:'' }; }, componentDidMount:function(){ this.serverRequest = $.get(this.props.source,function(data){ var lastGist = data[0]; this.setState({ username:lastGist.owner.login, lastGistUrl:lastGist.html_url }); }.bind(this)); }, componentWillUnmount:function(){ this.serverRequest.abort(); }, render:function(){ return ( <div> <h1>{this.state.username}用户最新的 Gist 共享地址:</h1> <a href={this.state.lastGistUrl}>{this.state.lastGistUrl}</a> </div> ); } }); ReactDOM.render( <UserGist source = "https://api.github.com/users/octocat/gists"/>, document.getElementById("example") ); </script>
</body>
</html>

React 表单与事件

Demo1:
这里创建了两个组件,子组件和父组件
onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。
这里需要在父组件通过创建事件句柄 (handleChange) ,并作为属性 (这里是upDataState) 传递到子组件上。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>react事件和表单</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../../build/react.js"></script>
    <script type="text/javascript" src="../../build/react-dom.js"></script>
    <script type="text/javascript" src="../../build/browser.min.js"></script>
    <script type="text/babel"> var Content = React.createClass({ render:function(){ return ( <div> <input type="text" value = {this.props.myData} onChange = {this.props.upDataState}/> <h1>{this.props.myData}</h1> </div> ); } }); var HelloMessage=React.createClass({ getInitialState:function(){ return {value:'hello react'}; }, handleChange:function(event){ this.setState({value:event.target.value}); }, render:function(){ var value=this.state.value; return ( <div> <Content myData = {value} upDataState = {this.handleChange}/> </div> ); } }); ReactDOM.render( <HelloMessage />, document.getElementById('example') ); </script>
</body>
</html>

当从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 属性 (updataState) 传递到你的子组件上。
Demo2:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>react事件与表单</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../../build/react.js"></script>
    <script type="text/javascript" src="../../build/react-dom.js"></script>
    <script type="text/javascript" src="../../build/browser.min.js"></script>
    <script type="text/babel"> var Content = React.createClass({ render:function(){ return ( <div> <button onClick = {this.props.updataState}>点击改变</button> <h1>{this.props.myData}</h1> </div> ); } }); var HelloMessage = React.createClass({ getInitialState:function(){ return { value:"Hello React" } }, handleClick:function(){ this.setState({ value:"Hello World" }); }, render:function(){ var value = this.state.value; return ( <div> <Content myData = {value} updataState ={this.handleClick}/> </div> ); } }); ReactDOM.render( <HelloMessage />, document.getElementById("example") ); </script>
</body>
</html>

React Refs

React 支持一种非常特殊的属性 Ref ,你可以用来绑定到 render() 输出的任何组件上。
这个特殊的属性允许你引用 render() 返回的相应的支撑实例。这样就可以确保在任何时间总是拿到正确的实例。
通过使用 this 来获取当前 React 组件,或使用 ref 来获取组件的引用
当组件插入到 DOM 后,ref 属性添加一个组件的引用于到 this.refs
Demo:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>React Ref</title>
</head>
<body>
    <div id="example"></div>
    <script type="text/javascript" src="../build/react.js"></script>
    <script type="text/javascript" src="../build/react-dom.js"></script>
    <script type="text/javascript" src="../build/browser.min.js"></script>
    <script type="text/babel"> var MyComponent = React.createClass({ handleClick:function(){ this.refs.myInput.focus(); }, render:function(){ return ( <div> <input type="text" ref = "myInput" /> <input type="button" value="点我输入框获取焦点" onClick = {this.handleClick}/> </div> ); } }); ReactDOM.render( <MyComponent />, document.getElementById("example") ); </script>
</body>
</html>

你可能感兴趣的:(react,JS框架)