react基础
整体结构(与一般html不同的)
1.react模块引入head中
<script src="../react.js"></script><!--react核心组件-->
<script src="../react-dom.js"></script><!--react操作dom-->
<script src="../browser.min.js"></script><!--将jsx语法转化成js-->
2.JSX,react基于JSX语法
script标签需要加type="text/babel"
,用于写JSX语法
3.如何渲染dom
<body>
<div class="example" id="example"></div>
<script type="text/babel">
ReactDOM.render( //render方法渲染
<MyComponent />,//组件
document.getElementById('example'))
</script>
</body>
如何写组件,组件demos
(1).遍历组件
//组件,首字母大写,用于输出组件类,返回的只能包含一个顶级标签
let PreList = React.createClass({///createClass用于生成组件类,
render : function () {//一定有一个render方法
//arr预设key值,做diff
let arr1 = [<h1 key="1">hello</h1>,<h1 key="2">bob</h1>,<h1 key="3">how are you?</h1>];//需要预设key,做diff对比时候用,要不报错
const arr2 = [1,2,3];
//{}代码块,写js,<>写html标签
return <div>
<div>
{arr1.map(function (val) {
return val;
})}
</div>
<ul>
{arr2.map(function (val,index) {
return <li key={index}>{val}</li>;//key值需要设,要不报错
})}
</ul>
</div>
}
});
(2).点击事件组件
let Button = React.createClass({
getDefaultProps:function () {//默认属性
return {name : 'click me'};
},
propTypes : {//属性,验证组件实例的属性是否符合要求
name : React.PropTypes.string.isRequired
},
loginClick :function () {
alert('点击生效')
},
render:function () {//onClick={this.loginClick},用括号包裹
return <div>
<button onClick={this.loginClick}>{this.props.name}</button>
</div>//this指的组件
}
});
(3).获取真实dom的输入
let RealDom = React.createClass({
loginClick :function () {//click事件确保用户点击了真实dom,才触发ref读取
this.refs.pwd.focus();//this.refs获取真实dom,有时候需要获取用户的输入,就需要真实的dom才能拿到
alert(this.refs.pwd.value);
},
render:function () {
return <div>
<input type="text" ref="pwd" name="pwd" title="pwd"/>
<button onClick={this.loginClick}>{this.props.name}</button>
</div>//this指的组件
}
});
(4).input变化监听
let InputChange = React.createClass({
getInitialState : function (){
return {
value : 'hello!' //用户填入表单中的属性属于可变,不能用props
}
},
changeInput:function (e) {
this.setState({value : e.target.value})
},
render :function () {
//onChange={this.changeInput}回调,用来读取用户输入的值,input/textarea/select/radio都是
return <div>
<input title="name" value={this.state.value} onChange={this.changeInput}/>
<p>{this.state.value}</p>
</div>
}
})
(5).带子节点的组件,处理
let Child = React.createClass({
render : function () {
//this.props.children,表示组件所有子节点,三种可能(undefined--没有,object--一个子节点,array--多个子节点)
//React.Children来处理this.props.children;
//React.Children.map遍历子节点,就不用担心this.props.children的数据类型
return <ul>
{React.Children.map(this.props.children,function (child) {
return <li>{child}</li>
})}
</ul>
}
});
(6).状态值变化
this.props:属性,最开始定义好就不再变化
this.state:会随着用户的变化而变化的状态值
let LikeButton = React.createClass({
getDefaultProps:function () {
return { bgColor : 'yellow'}
},
getInitialState : function (){//默认状态值设置
return {
like : false,
}
},
changeLike : function () {
this.setState({//修改状态值,每次状态值的修改,带动render的重新自动渲染
like : !this.state.like
})
},
render :function () {
var text = this.state.like? "like":"don't like";
//{{background:this.props.bgColor}} ,方式设置样式,React 组件样式是一个对象,第一个{}代表这是js语法,第二个{}代表是样式对象
return <div>
<button onClick={this.changeLike} style={{background:this.props.bgColor}}>{text}</button>
</div>
}
});
组件总控制器,包含组件的生命周期使用
/*总的组件控制器,集合*/
let MyComponent = React.createClass({
//组件的生命周期,三种,will函数在之前调用,did在之后调用
/**componentWillMount()
componentDidMount()
componentWillUpdate(object nextProps, object nextState)
componentDidUpdate(object prevProps, object prevState)
componentWillUnmount()
componentWillReceiveProps(object nextProps):已加载组件收到新的参数时调用
shouldComponentUpdate(object nextProps, object nextState):组件判断是否重新渲染时调用*/
componentWillMount:function () {
//插入真实dom前,
alert('dom not ok')
},
componentDidMount:function () {
//插入真实dom后,
alert('dom ok')
},
render :function () {
//如果不需要子节点,可以不用谢闭合双标签,这样<PreList/>就好
关于属性:class 属性需要写成 className ,for 属性需要写成 htmlFor ,这是因为 class 和 for 是 JavaScript 的保留字。
return <div>
<Button className="btn"/>
<RealDom name="点击"/>
<PreList/>
<Child>
<span>test child1</span>
<span>test child2</span>
</Child>
<LikeButton />
<InputChange />
</div>
}
});