React-2----react基础

1 认识

由facebook开发,只提供了MVC中的V。

优势:

①是组件化的,将js与html标签结合到一起

②单向数据流

③虚拟DOM树

下面为一段代码,初步认识react

<!DOCTYPE html>
<html lang="zh">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title></title>
</head>
<body>
	<div id="app">
		
	</div>
	<script type="text/babel">
		class HelloMessage extends React.Component {
		  render() {
		    return (
		      <div>
		        Hello {this.props.name}
		      </div>
		    );
		  }
		}
		
		ReactDOM.render(
		  <HelloMessage name="Taylor" />,
		  document.getElementById('app')
		);
	</script>
	<script src="https://cdn.bootcss.com/react/16.10.2/umd/react.development.js"></script>
	<script src="https://cdn.bootcss.com/react-dom/16.10.2/umd/react-dom.development.js"></script>
	<script src="https://cdn.bootcss.com/babel-standalone/7.0.0-beta.3/babel.js"></script>
</body>
</html>

2 create-react-app

有以下几个步骤

npm install -g create-react-app

create-react-app my-app

cd my-app

npm start

也可以打包

yarn build

3 第一个组件

首先引入bootstrap,在index.html里面

<link href="https://cdn.bootcss.com/twitter-bootstrap/4.0.0-beta.2/css/bootstrap.css" rel="stylesheet">

然后在App.js里面写代码

import React,{Component} from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
	render(){
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>hello world</h1>
				   </div>
			   </div>
			</div>
		)
	}
}


export default App;

4 剩下的内容

在src下新建一个components的目录,然后把组件都放到里边。我们新建一个header.js和home.js,内容分别为

import React,{Component} from 'react';


class header extends Component {
	render(){
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>header</h1>
				   </div>
			   </div>
			</div>
		)
	}
}


export default header;
import React,{Component} from 'react';

class home extends Component {
	render(){
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>home</h1>
				   </div>
			   </div>
			</div>
		)
	}
}


export default home;

然后在app.js里引用

import React,{Component} from 'react';
import Header from './components/header.js'
import Home from './components/home.js'

class App extends Component {
	render(){
		let content='';
		if(true){
		   content='hello'	
		}
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Header/>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>hello world</h1>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Home/>
					  {content}
					  {true ? 'hello':'world'}
				   </div>
			   </div>
			</div>
		)
	}
}


export default App;

动态数据:{}里面可以用三元运算符

props父组件向子组件传参和类型检查:

App.js

import React,{Component} from 'react';
import Header from './components/header.js'
import Home from './components/home.js'

class App extends Component {
	render(){
		let content='';
		if(true){
		   content='hello'	
		}
		const user={
			name:'Anna',
			hobbies:["sports","read"]
		}
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Header/>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>hello world</h1>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Home name={"Max"} age={12} user={user}>
					     <p>I am child</p>
					  </Home>
					  {content}
					  {true ? 'hello':'world'}
				   </div>
			   </div>
			</div>
		)
	}
}


export default App;

home.js

import React,{Component} from 'react';
import ProTypes from 'prop-types';

class home extends Component {
	render(){
		console.log(this.props);
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <div>name:{this.props.name}</div>
					  <div>age:{this.props.age}</div>
					  <h4>hobbies</h4>
					  <ul>
					    {this.props.user.hobbies.map((hobby)=><li key={hobby}>{hobby}</li>)}
					  </ul>
					  <div>{this.props.children}</div>
				   </div>
			   </div>
			</div>
		)
	}
}

// 检验数据类型
home.propTypes={
	name:ProTypes.string,
	age:ProTypes.number,
	user:ProTypes.object,
	children:ProTypes.element.isRequired
}

export default home;

state:更新DOM,只是部分渲染

import React,{Component} from 'react';
import ProTypes from 'prop-types';

class home extends Component {
	constructor(props){
		super(props);
		this.state={
			age:props.age
		}
	}
	
	onMakeMe(){
		this.setState({
			age:this.state.age + 1
		})
	}
	
	render(){
		console.log(this.props);
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <div>name:{this.props.name}</div>
					  <div>age:{this.state.age}</div>,
					  <h4>hobbies</h4>
					  <ul>
					    {this.props.user.hobbies.map((hobby)=><li key={hobby}>{hobby}</li>)}
					  </ul>
					  <div>{this.props.children}</div>
					  
					  <button onClick={()=>{this.onMakeMe()}} className="btn btn-primary">click me</button>
					  
				   </div>
			   </div>
			</div>
		)
	}
}

// 检验数据类型
home.propTypes={
	name:ProTypes.string,
	age:ProTypes.number,
	user:ProTypes.object,
	children:ProTypes.element.isRequired
}

export default home;

无状态组件:又叫函数式组件,指无状态改变的组件,没有生命周期

import React from 'react';

// 第一种写法
// class header extends Component {
// 	render{
// 		return (
// 			<div className="container">
// 			   <div className="row">
// 				   <div className="col-xs-1 col-xs-offset-11">
// 					  <h1>header</h1>
// 				   </div>
// 			   </div>
// 			</div>
// 		)
// 	}
// }

// 第二种写法,一般适用于无需state,即不需要处理用户的输入和不需要用到生命周期函数
//好处:1 不需要声明类,可以避免大量的比如extends和constructor的代码
//     2 不需要声明this关键字
const header = (props)=> {
	return (
		<div className="container">
		   <div className="row">
			   <div className="col-xs-1 col-xs-offset-11">
				  <h1>header</h1>
			   </div>
		   </div>
		</div>
	)
}


export default header;

如果后续又想改成有状态的组件,可以改。以后学。

子组件向父组件传参:

子组件:

import React,{Component} from 'react';
import ProTypes from 'prop-types';

class home extends Component {
	handleGreet(){
		this.props.greet(this.state.age)
	}
	
	render(){
		console.log(this.props);
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  
					  <button onClick={this.props.greet} className="btn btn-primary">greet</button>
					  <button onClick={this.handleGreet.bind(this)} className="btn btn-primary">handlegreet</button>
				   </div>
			   </div>
			</div>
		)
	}
}

export default home;

父组件:

import React,{Component} from 'react';
import Header from './components/header.js'
import Home from './components/home.js'

class App extends Component {
	onGreet(age){
		alert("hello!"+age)
	}
	
	render(){
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Header/>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>hello world</h1>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Home name={"Max"} age={12} user={user} greet={this.onGreet}>
					     <p>I am child</p>
					  </Home>
					  {content}
					  {true ? 'hello':'world'}
				   </div>
			   </div>
			</div>
		)
	}
}


export default App;

兄弟组件间传值和数据双向绑定、生命周期

app.js

import React,{Component} from 'react';
import Header from './components/header.js'
import Home from './components/home.js'

class App extends Component {
	constructor(){
		super();
		this.state={
			homeLink:'Home',
			homeMounted:true
		}
	}
	
	onGreet(age){
		alert("hello!"+age)
	}
	
	onChangeLinkName(newName){
		this.setState({
			homeLink:newName
		})
	}
	
	onChangeHomeMounted(){
		this.setState({
			homeMounted:!this.state.homeMounted
		})
	}
	
	render(){
		let content='';
		if(true){
		   content='hello'	
		}
		const user={
			name:'Anna',
			hobbies:["sports","read"]
		}
		
		let homeCap="";
		if(this.state.homeMounted){
			homeCap=(
			   <Home
			     name={"Max"} 
				 age={12} 
				 user={user} g
				 greet={this.onGreet}
				 initialName={this.state.homeLink}
				 changeLink={this.onChangeLinkName.bind(this)}>
			      <p>I am child</p>
			   </Home>);
		}
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <Header homeLink={this.state.homeLink}/>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <h1>hello world</h1>
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      {homeCap}
					  {content}
					  {true ? 'hello':'world'}
				   </div>
			   </div>
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
					  <button onClick={this.onChangeHomeMounted.bind(this)} className="btn btn-primary">component</button>
				   </div>
			   </div>
			</div>
		)
	}
}


export default App;

home.js

import React,{Component} from 'react';
import ProTypes from 'prop-types';

class home extends Component {
	constructor(props){
		super(props);
		this.state={
			age:props.age,
			homeLink:props.initialName
		}
	}
	
	onMakeMe(){
		this.setState({
			age:this.state.age + 1
		})
	}
	
	handleGreet(){
		this.props.greet(this.state.age)
	}
	
	onChangeLink(){
		this.props.changeLink(this.state.homeLink)
	}
	
	onHandleChange(event){
		this.setState({
			homeLink:event.target.value
		})
	}
	
	componentWillMount(){
		console.log('will mount')
	}
	
	componentDidMount(){
		console.log('did mount')
	}
	
	componentWillReceiveProps(nextProps){
		console.log('will receive props',nextProps)
	}
	
	shouldComponentUpdate(nextProps,nextState){
		console.log('should upstate',nextProps,nextState)
	}
	
	componentWillUpdate(nextProps,nextState){
		console.log('will upstate',nextProps,nextState)
	}
	
	componentDidUpdate(prevProps,prevState){
		console.log('did upstate',prevProps,prevState)
	}
	
	componentWillUnmount(){
		console.log('will unmount')
	}
	
	render(){
		console.log(this.props);
		return (
			<div className="container">
			   <div className="row">
			       <div className="col-xs-1 col-xs-offset-11">
				      <div>name:{this.props.name}</div>
					  <div>age:{this.state.age}</div>,
					  <h4>hobbies</h4>
					  <ul>
					    {this.props.user.hobbies.map((hobby)=><li key={hobby}>{hobby}</li>)}
					  </ul>
					  <div>{this.props.children}</div>
					  
					  <button onClick={()=>{this.onMakeMe()}} className="btn btn-primary">click me</button>
					  
					  <hr/>
					  
					  <button onClick={this.handleGreet.bind(this)} className="btn btn-primary">handlegreet</button>
					  
					  <hr/>
					  <input 
					    type="" 
						defaultValue={this.props.initialName} 
						value={this.state.initialName} 
						onChange={(event)=>this.onHandleChange(event)}/
					  >
					  
					  <button onClick={this.onChangeLink.bind(this)} className="btn btn-primary">Change Header Link</button>
				   </div>
			   </div>
			</div>
		)
	}
}

// 检验数据类型
home.propTypes={
	name:ProTypes.string,
	age:ProTypes.number,
	user:ProTypes.object,
	children:ProTypes.element.isRequired,
	initialName:ProTypes.string
}

export default home;

header.js

import React from 'react';

const header = (props)=> {
	return (
		<div className="container">
		   <div className="row">
			   <div className="col-xs-1 col-xs-offset-11">
				  <h1>header----{props.homeLink}</h1>
			   </div>
		   </div>
		</div>
	)
}


export default header;

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

  • Mounting:已插入真实 DOM(1,2)
  • Updating:正在被重新渲染(3,4,5,6)
  • Unmounting:已移出真实 DOM(7)

生命周期的方法有:

  • componentWillMount 在渲染前调用,在客户端也在服务端。

  • componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异步操作阻塞UI)。

  • componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

  • shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。
    可以在你确认不需要更新组件时使用。

  • componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

  • componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。

  • componentWillUnmount在组件从 DOM 中移除之前立刻被调用。

发布了110 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Lemontree_fu/article/details/103423171