React学习
JSF语法概述
const element = <h1>Hello, world!</h1>;
这个有趣的标签语法既不是字符串也不是 HTML。
它被称为 JSX,是一个 JavaScript 的语法扩展。我们建议在 React 中配合使用 JSX,JSX 可以很好地描述 UI 应该呈现出它应有交互的本质形式。JSX 可能会使人联想到模版语言,但它具有 JavaScript 的全部功能。
实例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
<script src="https://cdn.staticfile.org/react/16.4.0/umd/react.development.js"></script>
<script src="https://cdn.staticfile.org/react-dom/16.4.0/umd/react-dom.development.js"></script>
<!-- 生产环境中不建议使用 -->
<script src="https://cdn.staticfile.org/babel-standalone/6.26.0/babel.min.js"></script>
</head>
<body>
<div id="root"></div>
<script type="text/babel">
const name = 'linjinbao666';
const element = <h1>hello, {name}</h1>
ReactDOM.render(
element,
document.getElementById('root')
);
</script>
</body>
</html>
元素
元素是构成React
应用的最小砖块
元素的渲染
const element = <h1>Hello, world</h1>;
ReactDOM.render(element, document.getElementById('root'));
元素的更新
React
元素是不可变对象,创建后无法修改;可以通过创建一个全新的元素,并重新使用ReactDOM.render()
渲染。
组件
React
的组件和Vue
类似,注意点:
- 自定义首字母大写
<Welcome />
,原生组组件首字母大写,如:<div />
- 单标签
- 接受的参数是个对象,注意写法
/**
* @param {Object} props
* 组件
*/
function Welcome(props){
return <h1>组件, {props.name}</h1>;
}
const welcomeElement = <Welcome name="菜鸡从" />
ReactDOM.render(welcomeElement,document.getElementById('root'));
组合组件 组件可以在其输出中引用其他组件,这一特性可以用来建立文档树
结构,例如html
的dom
树
/**
* 组合组件
*/
function App(){
return(
<div>
<Welcome name="刘峰" />
<Welcome name="刘前" />
<Welcome name="我" />
</div>
)
}
const appElement = <App />
ReactDOM.render(appElement, document.getElementById('root'));
ES6定义组件格式
/**
* ES6定义组件
*/
class Clock extends React.Component{
constructor(props){
super(props);
this.state = {date:new Date().toDateString()};
}
render(){
return (
<div>
<h1>class 组件定义</h1>
<h2>现在是: {this.state.date}.</h2>
</div>
);
}
}
ReactDOM.render(<Clock />, document.getElementById('root'))
组件添加生命周期方法
componentDidMount()
方法会在组件已经渲染到DOM后运行
class Clock extends React.Component{
constructor(props){
super(props);
this.state = {date:new Date()};
}
//挂载函数
componentDidMount(){
this.timeID = setInterval(
() => this.tick(),1000
);
}
//清除函数
componentWillUnmount(){
clearInterval(this.timeID);
}
tick(){
this.setState({
date:new Date()
});
}
render(){
return (
<div>
<h1>class 组件定义</h1>
<h2>现在是: {this.state.date.toLocaleTimeString()}.</h2>
</div>
);
}
}
ReactDOM.render(<Clock />, document.getElementById('root'))
代码运行解释:
- 当
<Clock />
被传给ReactDOM.render()
的时候,React 会调用Clock
组件的构造函数。 因为Clock
需要显示当前的时间,所以它会用一个包含当前时间的对象来初始化this.state
。我们会在之后更新 state。 - 之后 React 会调用组件的
render()
方法。这就是 React 确定该在页面上展示什么的方式。然后 React 更新 DOM 来匹配Clock
渲染的输出。 - 当
Clock
的输出被插入到 DOM 中后, React 就会调用ComponentDidMount()
生命周期方法。在这个方法中,Clock
组件向浏览器请求设置一个计时器来每秒调用一次组件的tick()
方法。 - 浏览器每秒都会调用一次
tick()
方法。 在这方法之中,Clock
组件会通过调用setState()
来计划进行一次 UI 更新。得益于setState()
的调用,React 能够知道 state 已经改变了,然后会重新调用render()
方法来确定页面上该显示什么。这一次,render()
方法中的this.state.date
就不一样了,如此以来就会渲染输出更新过的时间。React 也会相应的更新 DOM。 - 一旦
Clock
组件从 DOM 中被移除,React 就会调用componentWillUnmount()
生命周期方法,这样计时器就停止了。
this.State
的赋值问题
- 在构造方法里面赋值
- 使用
setState
方法
事件处理
//事件处理
function ActionLink(){
function handleClick(e){
e.preventDefault();
console.log('The link is clicked.');
}
return(
<a href="#" onClick = {handleClick()}>
Click me
</a>
)
}
const actionElement = <ActionLink />
//ReactDOM.render(actionElement, document.getElementById('root3'));
//事件处理
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
this.handleClick = this.handleClick.bind(this);
}
handleClick(){
this.setState(state => ({
isToggleOn: !state.isToggleOn
}));
}
render(){
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? '开' : '关'}
</button>
)
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
)
条件渲染
React 中的条件渲染和 JavaScript 中的一样,使用 JavaScript 运算符```if`` 或者条件运算符去创建元素来表现当前的状态,然后让 React 根据它们来更新 UI。
//条件渲染
function UserGreeting(props){
return(
<h1>欢迎您,您已登录</h1>
)
}
function GuestGreeting(props){
return(
<h1>请先登录</h1>
)
}
/**
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
**/
class Greeting extends React.Component {
constructor(props) {
super(props)
this.isLoggedIn = props.isLoggedIn;
}
render(){
if (this.isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
}
ReactDOM.render(
<Greeting isLoggedIn = {false} />,
root3
)
代码示例:
function LoginButton(props) {
return (
<button onClick={props.onClick}>
登入
</button>
);
}
function LogoutButton(props) {
return (
<button onClick={props.onClick}>
登出
</button>
);
}
class LoginControl extends React.Component{
constructor(props){
super(props)
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedin: false}
}
handleLoginClick(){
this.setState({isLoggedIn: true});
}
handleLogoutClick(){
this.setState({isLoggedIn:false});
}
render(){
const isLoggedIn = this.state.isLoggedin;
let button;
if(isLoggedIn) button = <LogoutButton onClick = {this.handleLogoutClick} />;
button = <LoginButton onClick = {this.handleLoginClick} />;
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
)
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root2')
)