1.Hello World
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="app_wrap"></div>
<script type="text/javascript" src="dist/all.js"></script>
</body>
</html>
main.js
import React from "react";
import {render} from "react-dom";
import App from "./App.js";
render(
<App></App>,
document.getElementById("app_wrap")
)
App.js
import React from "react";
class App extends React.Component{
render() {
return <h1>hello</h1>
}
}
export default App;
2.函数、数组、样式
main.js
import React from "react";
import {render} from "react-dom";
import App from "./App.js";
//ES6形式定义组件的调用
render(
<App date={new Date()}></App>,
document.getElementById("app_wrap")
);
App.js
import React from "react";
//ES6形式定义组件
class App extends React.Component{
//类中定义的函数
haha(lanmu) {
if(lanmu="篮球") {
return (
<ul>
<li>乔丹</li>
<li>科比</li>
<li>沃尔</li>
</ul>
);
} else if(lanmu="足球") {
return (
<ul>
<li>djfh</li>
<li>dsfs</li>
<li>fhyg</li>
</ul>
);
}
};
render() {
//render中定义的函数
let xixi = () => {
return(
<div>
<h1>我是render中定义的函数:1+1={1+1}</h1>
</div>
);
}
//设置样式:方法二
let mystyle = {
"width":"600px",
"height":20+200+"px",
"backgroundColor":"gray",
"margin":"10px auto"
}
//数组:要求有key属性,属性值不能重复
let domarr = [
<h3 key="1">数组元素1</h3>,
<h3 key="2">数组元素2</h3>,
<h3 key="3">数组元素3</h3>
];
let arr = ["白板","妖姬","二手"].map((item,index)=>{
return <li key={index}>{item}</li>
});
return (
<div>
<h1>hello</h1>
<h2>北京时间:{this.props.date.toLocaleDateString()}</h2>
{/*调用类中的函数:加this*/}
{this.haha("篮球")}
{/*调用render中的函数*/}
{xixi()}
{/*设置样式:方法一*/}
<div style={{"width":"400px","height":20+200+"px","backgroundColor":"yellow","margin":"10px auto"}}></div>
{/*设置样式:方法二*/}
<div style={mystyle}></div>
{/*react数组(含有DOM)自动展开*/}
<div>{domarr}</div>
<div>{arr}</div>
</div>
);
}
}
export default App;
3.react的数据传递:state:自治的不涉及传值,props:父组件数据传递给子组件,context:祖先组件数据传递给后代组件
只有这三兄弟才会引发virtual DOM 的改变,从而改变DOM.
A.state:改变内部的值
show.js
import React from "react";
import {render} from "react-dom";
//连接State.js(状态)
import State from "./State.js";
render(
<State />,
document.getElementById("state")
)
state.js
import React from "react";
class State extends React.Component{
//构造函数:初始化状态
constructor() {
super();//要求调用super
this.state = {//定义state
a:100
}
}
add() {
this.setState({//改变state。改变a的值,只能用this.setState
a: this.state.a + 1 //不能写成++
})
}
render() {
return (
<div>
<p>{this.state.a}{/* 使用state */}</p>
<p><input type="button" value="点击" onClick={(this.add).bind(this)} /></p>
</div>
)
}
}
export default State;
B.props:父组件给子组件传递数据
安装prop-types:cnpm install --save-dev prop-types
show.js
import React from "react";
import {render} from "react-dom";
//连接Props.js(父组件数据传递给子组件)import Props from "./Props.js";
render(
<Props />,
document.getElementById("props")
)
props.js
import React from "react";
import Props2 from "./Props2.js";
class Props extends React.Component{
constructor() {
super();
}
render() {
return (
<div>
<Props2 name="旺旺" num={88} />
</div>
);
}
}
export default Props;
props2.js
import React from "react";
//引入PropTypes验证props的有效性
import {PropTypes} from "prop-types";
class Props2 extends React.Component{
constructor(param) {
super();
// alert(param.name);//构造函数中的参数param.name传入的是this.props.name
this.state = {
num:param.num //将param.name的值传给this.state.name,所以最终是将this.props.name值传给this.state.name
}
}
render() {
return (
<div>
<h1>复合组件:我是{this.props.name}</h1>{/* this.props是固定的,调用时属性为name,打印出name的属性值 */}
{/* props只能打印不能更改,数据是单向的 */}
{/* state能改变数据 */}
<h1>this.props.num为:{this.props.num}</h1>
<h1>this.state.num为:{this.state.num}</h1>{/* 调用this.state.num,值与上方相同 */}
<input type="button" value="num+1" onClick={()=>{this.setState({num:this.state.num + 1})}}/>
{/* 点击后this.state.num改变,this.props.num不变 */}
</div>
);
}
}
//组件传入的参数验证:当调用时没传入或传错类型name和num值时报错
//类名.propTypes
Props2.propTypes = {
name:PropTypes.string.isRequired,
num:PropTypes.number.isRequired
}
export default Props2;
C.子组件改变父组件的数据:
用奇淫技巧:父组件设置setState函数传递给子组件,子组件调用该函数并改变其值,使得父组件改变state从而改变数据
show.js
//连接PropsReverse.js 子组件改变父组件数据(后期用redux代替)
import PropsReverse from "./PropsReverse.js";
render(
<PropsReverse />,
document.getElementById("propsReverse")
)
PropsReverse.js
//子组件改变父组件数据(后期用redux代替)
import React from "react";
import PropsReverse2 from "./PropsReverse2.js";
class PropsReverse extends React.Component{
constructor() {
super();
this.state={
a:1
}
}
setA(number) {
this.setState({'a':number});
}
render() {
return (
<div>
<h1>我是PropsReverse父组件,我有一个a状态:{this.state.a}</h1>
<PropsReverse2 setA={(this.setA).bind(this)} a={this.state.a} />
</div>
);
}
}
export default PropsReverse;
PropsReverse2.js
import React from "react";
class PropsReverse2 extends React.Component {
constructor() {
super();
}
render() {
return (
<div>
<p>子组件收到父组件数据:{this.props.a}</p>
<input type="button" value="子更改父数据" onClick={()=>{this.props.setA(this.props.a+1)}} />
</div>
);
}
}
export default PropsReverse2;
D.context:可跨级传递数据,祖先的数据可传递给后代
改变爷爷数据值时,孙子接受爷爷的数据值也跟着改变
show.js
import React from "react";
import {render} from "react-dom";
//连接Yeye.js
import Yeye from "./Yeye.js";
render(
<Yeye />,
document.getElementById("yeye")
)
Yeye.js
import React from "react";
import Baba from "./Baba.js";
import {PropTypes} from "prop-types";
class Yeye extends React.Component{
constructor() {
super();
this.state = {
a:10
}
}
addA() {
this.setState({
a: this.state.a+1
})
}
render() {
return (
<div>
<h1>我是爷爷{this.state.a}</h1>
<input type="button" value="改变爷爷数据值" onClick={(this.addA).bind(this)} />
{/* 改变爷爷数据值时,孙子接受爷爷的数据值也跟着改变 */}
<Baba />
</div>
);
}
//获取家族共享的数据,并设置其值
getChildContext() {
return {
a:this.state.a
}
}
}
//家族共享数据的类型和要求
Yeye.childContextTypes = {
a:PropTypes.number.isRequired
}
export default Yeye;
Baba.js
import React from "react";
import Sunzi from "./Sunzi.js";
//引入PropTypes验证props的有效性
// import {PropTypes} from "prop-types";
class Baba extends React.Component{
constructor() {
super();
}
render() {
return (
<div>
<h1>我是爸爸</h1>
<Sunzi />
</div>
);
}
}
export default Baba;
Sunzi.js
import React from "react";
import {PropTypes} from "prop-types";
class Sunzi extends React.Component{
constructor() {
super();
}
render() {
return (
<div>
<h1>我是孙子</h1>
<p>通过context取得爷爷是数据:{this.context.a}</p>
</div>
);
}
}
//获取家族共享数据
Sunzi.contextTypes = {
a:PropTypes.number
}
export default Sunzi;
E.context:后代组件改变祖先组件数据:也是用奇淫技巧:共享祖先包含setState函数,后代组件调用该函数改值
Yeye.js
import React from "react";
import Baba from "./Baba.js";
import {PropTypes} from "prop-types";
class Yeye extends React.Component{
constructor() {
super();
this.state = {
a:10
}
}
addA() {
this.setState({
a: this.state.a+1
})
}
render() {
return (
<div>
<h1>我是爷爷{this.state.a}</h1>
<input type="button" value="改变爷爷数据值" onClick={(this.addA).bind(this)} />
{/* addA自己使用,改变爷爷数据值时,孙子接受爷爷的数据值也跟着改变 */}
<Baba />
</div>
);
}
//获取家族共享的数据,并设置其值
getChildContext() {
return {
a:this.state.a,
addA:(this.addA).bind(this) //将addA共享给后代
}
}
}
//家族共享数据的类型和要求
Yeye.childContextTypes = {
a:PropTypes.number.isRequired,
addA:PropTypes.func.isRequired
}
export default Yeye;
Sunzi.js
import React from "react";
import {PropTypes} from "prop-types";
class Sunzi extends React.Component{
constructor() {
super();
}
render() {
return (
<div>
<h1>我是孙子</h1>
<p>通过context取得爷爷是数据:{this.context.a}</p>
<input type="button" value="改变家族数据的值" onClick={this.context.addA} />
</div>
);
}
}
//获取家族共享数据
Sunzi.contextTypes = {
a:PropTypes.number,
addA:PropTypes.func
}
export default Sunzi;
4.实时表单输出
Realoutput.js
import React from "react";
class Realoutput extends React.Component{
constructor(props) {
super();
this.state = {
txt:"hello"
}
}
change(event) {
this.setState({
txt:event.target.value
})
}
render() {
return (
<div>
<input type="text" onInput={(this.change).bind(this)} />
<p>{this.state.txt}</p>
</div>
);
}
}
export default Realoutput;
5.ref:DOM钩子
Ref.js
//ref:DOM钩子
import React from "react";
class Ref extends React.Component{
constructor() {
super();
}
render() {
return (
<div>
<input type="button" value="盒子变色" onClick={()=>this.refs.mybox.style.backgroundColor="yellow"} />
<div className="box" ref="mybox" style={{"width":200,"height":200,"backgroundColor":"red"}}></div>
</div>
);
}
}
export default Ref;