ReactDOM.render 是 React 的最基本方法,用于将模板转为 HTML 语言,并插入指定的 DOM 节点。
ReactDOM.render(
<h1>Hello, React!</h1>,
document.getElementById('example')
);
上面代码将一个 h1 标题,插入 example 节点
React 使用 JSX 来替代常规的 JavaScript。
JSX的优点:
在 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')
);
React 可以渲染 HTML 标签 (strings) 或 React 组件 (classes)。
var myDivElement = <div className="foo" />;
ReactDOM.render(myDivElement, document.getElementById('example'));
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 来做对应的属性。
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 对象
注意:
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>
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 为每个状态都提供了两种处理函数,will 函数在进入状态之前调用,did 函数在进入状态之后调用,三种状态共计五种处理函数:
React 的两种特殊状态的处理函数:
<!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 组件的数据可以通过 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>
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 支持一种非常特殊的属性 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>