React特点
1.一套用于构建用户页面的js框架
2.基于组件开发
3.虚拟DOM
这是React最重要的特性,放进内存,最小,差异部分更新 ,使得性能卓越,开销很小(频繁的DOM操作,会造成资源浪费)
diff算法: 一个比较计算层次结构区别的算法,用来计算DOM之间的差异
4.数据流(data flow) 单向数据流
JSX语法
1. JSX是Javascript和XML联系在了一起,它不能直接运行,必须使用翻译器(bable)将它转换为JS才能运行。
2. React发明了JSX,利用HTML语法来创建虚拟DOM。当遇到<,JSX就当HTML解析,遇到{就当JavaScript解析。
3.我们可以在 JSX 中使用 JavaScript 表达式。表达式写在花括号 {} 中。
4.在JSX中使用样式和真实的样式也很类似,通过style属性来定义,但和真实DOM不同的是,属性值不能是字符串而必须为对
象。要明确记住,{}里面是JS代码,这里传进去的是标准的JS对象。在JSX中可以使用所有的的样式,基本上属性名的转换规范就是
将其写成驼峰写法,例如“background-color”变为“backgroundColor”, “font-size”变为“fontSize”,这和标准的
JavaScript操作DOM样式的API是一致的。
5. JSX扩展属性
使用ES6的语法
var props={ };
props.foo="1";
props.bar="1";
`<h1 {...props} foo ="2">hello world</h1>`
6。自定义属性
HTML5给出了方案,凡是以data-开头的自定义属性,可渲染到页面
7.显示HTML 显示一段HTML字符串,而不是HTML节点
借助一个属性 _html
`<div>{{_html:`<h1>hello world</h1>`}}</div>`
4)事件绑定 调用bind方法(设定作用域,要传递的参数)
<body>
<div id="example"></div>
<script type="text/babel">
function testClick(msg){
alert(msg);
}
var app=<button onClick={testClick.bind(this,'hello')} style={{
backgroundColor:'#ff0000',
fontSize:'28px',
width:'200px',
height:'100px'
}} >点击我吧</button>
React.render(app ,document.getElementById('example'))
</script>
</body>
ReactDOM.render是React的最基本的方法,用于将模板转换为html语言,并插入到DOM检点中。(什么东西渲染到哪里去)
组件及属性
<body>
<!--容器-->
<div id="container"></div>
<script type="text/babel">
//创建一个组件
var Nana = React.createClass({
//所有的组件必须有自己的render
//组件类的名字第一个字母必须大写
render: function () {
return (
//每个组件只能有一个标签
<div>
<h2>{this.props.titile}</h2> //this指的是自定义的组件Nana
<p>{this.props.r}</p>
</div>
);
}
}
);
//在调用的时候,如果想要调用多次组件,也需要给组件一个根标签
ReactDOM.render(
<div>
<Nana titile="a" r="aa" />
<Nana titile="b" r="bb"/>
</div>,
document.getElementById("container")
);
</script>
事件的使用
<body>
<div id="container"></div>
<script type="text/babel">
var Nana = React.createClass({
edit: function () {
alert('hello');
},
remove: function () {
alert('world');
},
render: function () {
return (
<div>
<button onClick={this.edit}></button>
<button onClick={this.remove}></button>
</div>);
}
});
ReactDOM.render(
//渲染视图
<div>
<Nana/>
<Nana/>
</div>,
document.getElementById("container"));
</script>
</body>
状态及应用
<body>
<div id="container"></div>
<script type="text/babel">
var CheckBox = React.createClass({ //{}里面全是方法
getInitialState: function () { //初始化一个状态值,返回一个对象,准备组件需要的数据以及后面需要的数据模型,返回值挂载在this.state上
return {
checked: false
}
},
handleChecked: function () {
this.setState({checked: !this.state.checked}); //设置状态
},
render: function () {
var msg;
if (this.state.checked) {
msg = "checked";
} else {
msg = "unchecked";
}
return (
<div>
<input type="checkbox" onChange={this.handleChecked} defaultChecked={this.state.checked}/>
<h3>check is{msg}</h3>
</div>
);
}
});
ReactDOM.render(
<CheckBox/>,
document.getElementById("container")
);
</script>
</body>
状态组件应用
<body>
<div id="container"></div>
<script type="text/babel">
var Nana = React.createClass({
getInitialState:function(){
return({editing:false});
},
edit: function () {
this.setState({editing:true})
},
remove: function () {
alert('world');
},
save:function(){
this.setState({editing:false})
},
renderNormal:function(){
return(
<div>
<button onClick={this.edit}></button>
<button onClick={this.remove}></button>
</div>
);
},
renderForm:function(){
return(
<div>
<Textarea defaultaValue={this.props.children}></Textarea>
<button onClick={this.save}>save</button>
</div>
)
},
render: function () {
if (this.state,editing){
return this.renderForm();
}else{
return this.renderNormal();
}
}
});
ReactDOM.render(
<div>
<Nana/>
<Nana/>
</div>,
document.getElementById("container"));
</script>
</body>
通过this.state改变视图
1. props属性:组件可以定义初始值,自己不可更改props属性值,只允许从父组件中传递过来:
2. state属性:组件用来改变自己状态的属性,通常使用setState({key:value})来改变属性值,不能使用this.state.xxx来直接改变,setState({key:value})方法会触发界面刷新。ReactJs内部会自动监听state属性的变化,一旦发生变化,就会主动触发组件的render方法来更新虚拟DOM结构。
3. 虚拟DOM:将真实的DOM结构映射成一个JSON数据结构
对于经常改变的数据且需要刷新界面显示,可以使用state。对于不需要改变的属性值可以使用props。React Native建议由顶层的父组件定义state值,并将state值作为子组件的props属性值传递给子组件,这样可以保持单一的数据传递。
var ShowEditor=React.createClass(
{
getInitialState:function(){
return {value:'你可以在这里输入文字'};
},
handleChange:function(){
this.setState({value:React.findDOMNode(this.refs.textarea).value});
},
render:function(){
return (
<div>
<h3>输入</h3>
<textarea style={{width:300,height:150,outline:'none'}}
onChange={this.handleChange} //监听
ref="textarea"
defaultValue={this.state.value}
/>
<h3>输出</h3>
<div> {this.state.value} </div>
</div>
);
}
}
);
React.render(<ShowEditor />,document.getElementById('example'));
组件生命周期
我们把组件从装载,到渲染,再到卸载当做一次生命周期,也就是组件的生存状态从装载开始到卸载为止,期间可以根据属性的变化进行多次渲染。
生命周期的方法就是组件在不同虚拟DOM中不同状态的描述。
挂载
挂载指的是组件的实例被创建并插入到DOM中,挂载会调用如下的方法
constructor :RN组件的构造方法,它在RN组件被挂载前被调用(在constructor中初始化状态state,然后在需要修改时调用setState方法)
1.创建阶段
getDefaultProps方法:处理props的默认值,在React.createClass时调用。
props是一个对象,组件用来接收外部参数,组件内部不能修改props,只能通过父组件来修改,
2.实例化阶段
触发getInitialState, componentWillMount, render, componentDidMount这四个函数的回调
componentWillMount(),组件开始装载之前调用,在一次生命周期中只会执行一次。
componentDidMount(),组件完成装载之后调用,在一次生命周期中只会执行一次,从这里开始就可以对组件进行各种操作了,比如在组件装载完成后要显示的时候执行动画。
3.更新阶段
componentWillUpdate(object nextProps, object nextState),组件属性更新之前调用,每一次属性更新都会调用 componentDidUpdate(object prevProps, object prevState),组件属性更新之后调用,每次属性更新都会调用
4.销毁阶段
componentWillUnmount(),组件卸载之前调用
<body>
<div id="example"></div>
<script type="text/babel">
var HelloMessage=React.createClass(
{
//1、创建阶段
getDefaultProps:function(){
//在创建类的时候被调用 this.props该组件的默认属性
console.log("getDefaultProps");
return {};
},
//2、实例化阶段
getInitialState:function(){
//初始化组件的state值,其返回值会赋值给组件的this.state属性
//获取this.state的默认值
console.log("getInitialState");
return {};
},
componentWillMount:function(){
//在render之前调用此方法
//业务逻辑的处理都应该放在这里,如对state的操作等
console.log("componentWillMount");
},
render:function(){
//根据state值,渲染并返回一个虚拟DOM
console.log("render");
return <h1 style={{color:'#ff0000',fontSize:'24px'}} >Hello {this.props.name}!我是东方耀</h1>;
//这是注释 React.createElement
},
componentDidMount:function(){
//该方便发生在render方法之后
//在该方法中,ReactJS会使用render方法返回的虚拟DOM对象来创建真实的DOM结构
//组件内部可以通过this.getDOMNode()来获取当前组件的节点
console.log("componentDidMount");
},
//3、更新阶段,主要发生在用户操作之后或父组件有更新的时候,此时会根据用户的操作行为进行相应的页面结构的调整
componentWillReceiveProps:function(){
//该方法发生在this.props被修改或父组件调用setProps()方法之后
//调用this.setState方法来完成对state的修改
console.log("componentWillRecieveProps");
},
shouldComponentUpdate:function() {
//用来拦截新的props或state,根据逻辑来判断
//是否需要更新
console.log("shouldComponentUpdate");
return true;
},
componentWillUpdate:function(){
//shouldComponentUpdate返回true的时候执行
//组件将更新
console.log("componentWillUpdate");
},
componentDidUpdate:function(){
//组件更新完毕,我们常在这里做一些DOM操作
console.log("componentDidUpdate");
},
//4、销毁阶段
componentWillUnmount:function(){
//销毁时被调用,通常做一些取消事件绑定、移除虚拟DOM中对应的组件数据结构、销毁一些无效的定时器等工作
console.log("componentWillUnmount");
}
}
);
ReactDOM.render(<HelloMessage name="React 语法基础8" /> ,document.getElementById('example'));
</script>
</body>
组件间通信
1.子组件如何调用父组件
this.props
2.父组件如何调用子组件
ref可以拿到子组件的所有属性
首先用属性ref给组件取个名字
this.refs.名字.getDOMNode().
(补充:获取真实的DOM节点
组件并不是真实的 DOM 节点,而是存在于内存之中的一种数据结构,叫做虚拟 DOM (virtual DOM)。只有当它插入文档以后,才会变成真实的 DOM 。
有时需要从组件获取真实 DOM 的节点,这时就要用到 ref 属性。
为了获取真是DOM节点,html元素必须有一个 ref 属性,然后 this.refs.[refName] 就会返回这个真实的 DOM 节点。需要注意的是,由于 this.refs.[refName] 属性获取的是真实 DOM ,所以必须等到虚拟 DOM 插入文档以后,才能使用这个属性,否则会报错。)
<body>
<div id="example"></div>
<script type="text/babel">
var Parent=React.createClass(
{
click:function(){
this.refs.child.getDOMNode().style.color="red";
},
render:function(){
return (
<div onClick={this.click} >Parent is :
<Child name={this.props.name} ref="child"></Child>
</div>
);
}
}
);
var Child=React.createClass({
render:function(){
return <span> {this.props.name} </span>;
}
});
ReactDOM.render(<Parent name="React语法基础" /> ,document.getElementById('example'));
</script>
原文发布时间:2018年05月13日
原文作者:Rqlinna
本文来源csdn如需转载请紧急联系作者