ES6 react.js 开发实践笔记
2017-05-05 本文已影响17人
泡芙小姐110
react构建指南
1,使用react需要用到脚手架 create react -app
使用之前需要装有node ,因为需要用到node的npm
安装的时候需要全局安装一个包,然后找个地方安装myapp
替换淘宝镜像 $ npm install cnpm -g --registry=https://registry.npm.taobao.org
以后使用cnpm会更快一些。
2,需要react router 路由管理
安装所必须要的包:
npm install --save-dev react-router
npm install --save-dev react-router-dom
1,props
1,props初始化的时候使用,state是交互的时候使用,仅用户交互,会随着事件改变
2,需要从父组件传递用props,随着时间推移不会改变用props
3,props不给初始值的话,会默认为true,但是不建议不给初始值
4,Text.defaultProps={//defaultProps可以给Text组件添加props
name:"hello"
}
5,传递props值,可以用<Greeting {...props}/>但是谨慎使用
组件类 :
<Mytab name="abcd" age="aaa"/>,//是一个React组件类大写
component:
<span>{this.props.name},{this.props,age}</span>//在组件的时候获取的时候用
特点:1,属性不好改,定死的
2,props一般用来传递数据,父组件向子组件传递数据。
2,state
1,constructor(props){super(props)}//组件应该始终调用基础构造函数,一般来说是初始化组件的时候执行的。
2,在constructor里面可以直接this.state={};给state赋值
3,在其他方法里面不允许这么写。需要this.setState({...})
4,this.props和this.state是队列更新dom,所以有可能会有没排队跟上的情况,不应该用他的上一次值来做操作。解决 的办法是用setState()来接受一个函数而不是上述对象,
this.setState((prevState, props)=>({
counter:prevState.counter+props.increment
}))
3,事件
1,react建议直接把监听事件写在dom中
2,on...事件监听只能作用于普通的html标签上,不能适用于组件上面
2,onClick={this.click}//绑定事件驼峰命名,写法如此
3,需要在construtor(){ this.click=this.click.bind(this)}//进行事件绑定
然后lick(){this.setState({name:"000"})//才可以设置state的值}//不然设置不了state的值
4,如果嫌麻烦不愿bind,可以直接写成
click=()=>this.setState({name:"000"})//绑定事件第二种方法,就不用bind绑定了,是ES6写法
或者onClick={()=>this.click()}; 然后click(){this.setState({name:"000"})}//这样也不用绑定bind了
4,组件
1,如果一个新组件 retrun null或者retrun false,则这个新组件讲不会显示,但是会执行生命周期方法。
2, {a&&<span>aa</span>},如果a有值或者是true,则显示aa组件,否则不显示
3,false,null,undefined,值为这些的条件都不渲染。
4,不受控组件的解决方案:
<input type="checkbox">和<input type="radio">支持defaultChecked,//不能直接使用checked因为使用了就不可变了
<select>与<textarea>和<input/>支持defaultValue。//不能直接使用value因为使用了就不可变了
5,forceUpdate就是手动重新render。有些变量不在state上,但是你又想达到这个变量
更新的时候,刷新render;
或者state里的某个变量层次太深,更新的时候没有自动触发render。
这些时候都可以手动调用forceUpdate自动触发render。所以建议使用immutable来操
作state,redux等flux架构来管理state。
6,如果shouldComponentUpdate返回false,则render()不会被调用,就不更新状态。
5,组件之间的通信
1,父组件可以通过props的方式向子组件传值
2,父组件可以通过{...this.props}的方式传入更深层子孙组件如:
// 通过 ... 运算符 向 Child_1_1 传递 Parent 组件的信息
class Child_1 extends Component{
render() {
return <div>
<p>{this.props.msg}</p>
<Child_1_1 {...this.props}/>
</div>
}
}
class Child_1_1 extends Component{
render() {
return <p>{this.props.msg}</p>
}
}
3,子向父组件通信
//可以利用回调函数
class Parent extends Component{ //父组件
state = {// es7语法
msg: ''
};
val=(data)=> this.setState(mag:data); //父组件的props中val方法
render() {
return <div>
<p>child msg: {this.state.msg}</p>
<Child value = {this.val} />//父组件的props
</div>;
}
}
class Child extends Component{//子组件
click(){
this.props.valuel('可以可以是随便的值,也可是是此子组件的state')
}
render(){
return <div><button onClick={this.click} >点击通信</button></div>
}
}
3,兄弟之间的通信 就是借助父组件做为中间桥梁,进行通信的。
4,兄弟之间的这种通信模式会触发很多次生命周期,故需要一种观察者模式import eventProxy from '../eventProxy。还有更好的解决方式,redux,后续跟进。
5,列表和秘钥
1,可以使用map()来渲染li列表
function NumberList(props) {
let number=props.numbers;
let numlist=number.map((n)=> <Listi key={n.toString()} value={n}/>);//一定要加key区别与其他列表。
return <ul>{numlist}</ul>
}
function Listi(props){
return <li>{props.value+1}</li> //key不应写在这里,应写在根元素,可以在这里做数据操作+1
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
6,froms表单
1,普通的表单提交如果用在react上,实现这一点的标准方法就是一种称为受控组件的技术
2,textarea,select,input checkbox同样受用.
class NameForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: ''};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
alert('A name was submitted: ' + this.state.value);
event.preventDefault();
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Name:
<input type="text" value={this.state.value} onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
);
}
}
7,propsTypes
1,PropTypes导出一系列验证器,可用于确保您接收的数据有效
2,PropsTypeys提供了不同的验证器
import PropTypes from 'prop-types';
class Greeting extends React.Component {
render() {
return (
<h1>Hello, {this.props.name}</h1>
);
}
}
Greeting.propTypes = {
name: PropTypes.string
};
8,ref和js中的DOM操作
1,react封装了很多个.on事件,几乎不需要和dom直接打交道,react其实也建议过多的使用ref
1,ref就相当于一个DOM挂钩,在某个元素上设置ref,就可以取得这个DOM元素进行操作。
onclick(){ //点击获取ref设置的this.in的挂钩,进行DOM操作
this.in.focus();
}
render(){
return (
<div>
测试: <input ref={(input)=>{this.in=input;}} type="text" />//设置ref,this.in就是此input
<button onClick={this.onclick}>点击获取input焦点</button>
</div>
)
}
**4,注意{{}}**
<span tyle={{display:none}}}> 我是span1</span>//style要放到{{}}里面
容器组件
1,只放容器的组件,注意有结束标签
<BlackBorderContainer>
<div className='name'>My Name:Lucy</div>
<p className='age'>
My Age:<span>12</span>
</p>
</BlackBorderContainer>
class BlackBorderContainer extends Component{
render(){
return (<div>
{this.props.children[1]}<hr/>{this.props.children[0]}
</div>)
}
}
组件的生命周期
-> constructor() //初始化一些状态
-> componentWillMount() // 加载ajax
-> render()
// 然后构造 DOM 元素插入页面
-> componentDidMount()
// ...
// 即将从页面中删除
-> componentWillUnmount()//清除一些状态机
// 从页面中删除
componentWillMount(),创建之前
componentDidMount(),创建之后
组件输出已经呈现给DOM后,
componentWillReceiveProps()//组件的参数更新时,就是组件接受一个新的任务
componentWillUpdate(),更新之前
componentDidMount(),更新之后
componentWillUnmount() 组件对应的 DOM 元素从页面中删除之前调用
5,组件里面可以有子组件
6,创建列表 Mocha 调试用的 react全家桶系列之一
里面的有一个key 值,用来识别dom的唯一性,react发现如何存在就不重新创建,如果无就新建
下午创建一个列表
7,组件内的节点
node 标签
怎么操作需要渲染的标签
ref 类似于id
ref=“f1”
取 this.refs["f1]
8,在constructor中其实组件并没有完全准备好,因为组件还没有彻底渲染出来。所以使用refs的时候,一定要注意。
9,默认值,可以用default Value Checked 这样是可以改的
10,事件冒泡:
Origin
1、React并不会通过String类型的Html片段生成DOM
2、在componentWillReceiveProps中调用setState()不会触发re-render
3、componentWillUpdate中不能调用this.setState()
4、在通过Ajax获取到数据,调用this.setState()之前,应该通过this.isMounted()确定当前的component已经处在渲染完成的阶段
5、父组件到子组件通过props传递数据,子组件向父组件传递数据通过global event方式来处理,即在root element上接受所有子组件的事件处理
6、移动设备的touch事件需手动开启:React.initializeTouchEvents(true)
7、setState(data, callback)中的callback是在re-render完成之后调用的
61,简答的输出
> ```class Mytab1 extends React.Component{
render(){
return(<div>
<span> 我是span1</span>
<span> 我是span2</span>
<span>我是span3</span></div>
)
}
}
class Mytab extends React.Component{
render(){
return (<div><ul className="tab">
<li>home</li>
<li>about us1</li>
<li>about us2</li>
<li>about us3</li>
<li>about us4</li>
</ul>
<Mytab1/>//组件类
</div>);
}
}
ReactDOM.render(
<Mytab/>,//是一个React组件类
document.getElementById('example')
);