0913 NOTE
React是什么?
一个将数据渲染为HTML视图的js库
React的特点:
1.采用组件化模式,声明式编码,提高开发效率及组件复用率
2.React Native中可以使用React语法进行移动端开发
3.虚拟DOM+优秀的Diffing算法,尽量减少与真实DOM的交互
React实现:
数据=>虚拟DOM=>真实DOM
虚拟DOM的两种创建方式
1.js创建
React.createElement('h1',{id:"title"},React.createElement('span',{},"Hello React"))
ReactDOM.render(VDOM,document.getElementById('test'))
2.jsx创建
<script type="text/babel">
let VDOM = <h1 id="title"><span>Hello,React</span></h1>;
ReactDOM.render(VDOM,document.getElementById('test'));
</script>
jsx出现的原因:解决虚拟DOm创建的繁琐问题,实际是原生js的语法糖
虚拟DOM与真实DOM
虚拟DOM:
? 1.本质是一般对象
? 2.虚拟DOM用于React内部,没有真实DOM那么多的属性
? 3.虚拟DOM最终会被React转化为真实DOM,呈现在页面上
jsx语法规则
? jsx:javascript XML js扩展语法
? 语法规则:
? 1.定义虚拟DOM时,不写引号
? 2.标签中想借用js表达式调用变量时,用{}包含变量名
? 3.jsx中,样式类名指定用className而不是class
? 4.jsx中,内联样式需用双括号包裹对象而非字符串
? 5.虚拟DOM只允许有一个根标签
? 6.标签必须闭合
? 7.标签首字母:
? a.小写字母开头,则将该标签转为html中同名元素,若无对应html元素,报错
? b.大写字母开头,则react会去渲染对应组件,组件未定义则报错
组件与模块
模块:复用js,简化js编写,提高js运行效率
组件:服用代码,简化项目代码,提高运行效率
组件定义方式
函数式组件:
<script type="text/babel">
function Demo(){
return <h2>reacttest</h2>
}
ReactDOM.render(<Demo/>,document.qetElementById("test"))
</script>
步骤:
? 创建函数式组件:
? React解析组件标签→找到对应组件→发现组件由函数定义,调用该函数,将返回的虚拟DOM转为真实DOM,渲染呈现在页面中
function Demo(){
return <h2>reacttest</h2>
}
ReactDOM.render(<Demo/>,document.qetElementById("test"))
注:babel编译后js环境进入严格模式
类式组件:
类式组件创建必须继承react中的内置类React.Component
class MyTest extends React.Component{
render(){
return <h1><span>Hello,React</span></h1>
}
}
复杂组件的定义:
? 与简单组件的区别→复杂组件有状态state
状态state是组件实例上的属性
初始化state:
class MyTest extends React.Component{
constructor(props){
super(props)
}
render(){
return <h1><span>Hello,React</span></h1>
}
}
react中的事件绑定的注意事项:
? 1.小驼峰命名,如onClick,不符合命名规则报错
? 2.行内属性实现事件监听时,通过花括号将事件函数传入,与原生js给入字符串,解析成函数不同,对比:οnclick=“clickHandler”||onClick={clickHandler}
? 3.类中方法默认开启了局部的严格模式,需要注意this指向问题
setState的使用
注意:状态不可直接更改,需要借助内置API:setState更改
class Weather extends React.Component{
constructor(props){
console.log('constructor');
super(props)
this.state = {isHot:false,wind:'微风'}
this.changeWeather = this.changeWeather.bind(this)
}
render(){
console.log('render');
const {isHot,wind} = this.state
return <h1 onClick={this.changeWeather}>今天天气很{isHot ? '炎热' : '凉爽'},{wind}</h1>
}
changeWeather(){
console.log('changeWeather');
const isHot = this.state.isHot
this.setState({isHot:!isHot})
console.log(this);
}
}
ReactDOM.render(<Weather/>,document.getElementById('test'))
state简写:
class MyTest extends React.Component {
state = {isTrue:false};
render() {
let {isTrue} = this.state;
return <h1><span onClick={this.changetalk}>你说的{isTrue ? "对" : "不对"}!</span></h1>
};
changetalk = ()=>{
let isTrue = this.state.isTrue;
this.setState({isTrue : !isTrue})
}
}
ReactDOM.render(<MyTest />, document.getElementById("test"))
props属性
基本使用:
class Person extends React.Component {
render() {
let { pname, page, pgender } = this.props;
return (
<ul>
<li>姓名:{pname}</li>
<li>性别:{pgender}</li>
<li>年龄:{page}</li>
</ul>
)
}
}
ReactDOM.render(<Person pname="凯哥" pgender="男" page="18" />,document.getElementById("test1"))
ReactDOM.render(<Person pname="小胖砸" pgender="男" page="666" />,document.getElementById("test2"));
ReactDOM.render(<Person pname="小菜鸟" pgender="男" page="888" />,document.getElementById("test3"));
批量传递:
? 注意:
? 1.展开运算符…在react的babel标签中可以展开对象,但是仅适用于标签属性
? 2.props只读
class Person extends React.Component {
render() {
let { pname, page, pgender } = this.props;
return (
<ul>
<li>姓名:{pname}</li>
<li>性别:{pgender}</li>
<li>年龄:{page+1}</li>
</ul>
)
}
}
Person.defaultProps = {
pgender:"小样,居然想性别保密?",
page:999,
}
Person.propTypes = {
pname:PropTypes.string.isRequired,
pgender:PropTypes.string,
page:PropTypes.number,
}
let kaige = {pname:"凯哥",pgender:"男",page:18};
let xiaopang = {pname:"小胖砸",pgender:"男",page:666};
let cainiao = {pname:"小菜鸟",pgender:"男",page:"888"};
ReactDOM.render(<Person {...kaige} />, document.getElementById("test1"));
ReactDOM.render(<Person {...xiaopang} />, document.getElementById("test2"));
ReactDOM.render(<Person pname="小菜鸟" />, document.getElementById("test3"));
props简写:
class Person extends React.Component {
render() {
let { pname, page, pgender } = this.props;
return (
<ul>
<li>姓名:{pname}</li>
<li>性别:{pgender}</li>
<li>年龄:{page + 1}</li>
</ul>
)
}
static defaultProps = {
pgender: "小样,居然想性别保密?",
page: 999,
}
static propTypes = {
pname: PropTypes.string.isRequired,
pgender: PropTypes.string,
page: PropTypes.number,
}
}
let kaige = { pname: "凯哥", pgender: "男", page: 18 };
let xiaopang = { pname: "小胖砸", pgender: "男", page: 666 };
let cainiao = { pname: "小菜鸟", pgender: "男", page: "888" };
ReactDOM.render(<Person {...kaige} />, document.getElementById("test1"));
ReactDOM.render(<Person {...xiaopang} />, document.getElementById("test2"));
ReactDOM.render(<Person pname="小菜鸟" />, document.getElementById("test3"));
类式组件中的构造函数与props
? 通常,在 React 中,构造函数仅用于以下两种情况:
? 1.通过给 this.state 赋值对象来初始化内部 state。
? 2.为事件处理函数绑定实例
? 在为 React.Component 子类实现构造函数时,应在其他语句之前前调用 super(props) 。否则,this.props 在构造函数中可能会出现未定义的 bug。
函数式组件使用props
function Person(props) {
let { pname, page, pgender } = props;
return (
<ul>
<li>姓名:{pname}</li>
<li>性别:{pgender}</li>
<li>年龄:{page + 1}</li>
</ul>
)
}
Person.defaultProps = {
pgender: "小样,居然想性别保密?",
page: 999,
}
Person.propTypes = {
pname: PropTypes.string.isRequired,
pgender: PropTypes.string,
page: PropTypes.number,
}
let kaige = { pname: "凯哥", pgender: "男", page: 18 };
let xiaopang = { pname: "小胖砸", pgender: "男", page: 666 };
let cainiao = { pname: "小菜鸟", pgender: "男", page: 888 };
ReactDOM.render(<Person {...kaige} />, document.getElementById("test1"));
ReactDOM.render(<Person {...xiaopang} />, document.getElementById("test2"));
ReactDOM.render(<Person {...cainiao} />, document.getElementById("test3"));
注意:函数式组件调用props属性没问题,但是无法调用state与refs,除非通过hooks
视频参考
|