摘要:语法是一种语法的拓展语言,在中官方也推荐使用描述用户界面,使用起来会比较快捷而且易读不是一门新的语言,可以理解为是一种语法糖,作用就是能够让我们更加直观的在中创建标签,最终还是会被编译为语法,例如我们看一段代码上面的语法最终会被编译为语法,
Reatc JSX语法
jsx是一种JavaScript语法的拓展语言,在React中官方也推荐使用jsx描述用户界面,使用起来会比较快捷而且易读
jsx不是一门新的语言,可以理解为是一种语法糖,作用就是能够让我们更加直观的在js中创建html标签,jsx最终还是会被编译为JavaScript语法,例如我们看一段jsx代码:
/*jsx*/ ReactDOM.render(, document.querySelector("#root") )hello world
上面的jsx语法最终会被编译为JavaScript语法,中间就是通过一个React.createElement的方法来转化,转换后就是下面这段代码
ReactDOM.render( React.createElement( "div", {className:"wrap"}, "", React.createElement( "h1", null, "hello world" ) ), document.querySelector("#root") )
比较两段代码就可以看出来使用js语法来写的话实在不够简练,所以我们通常还是使用jsx的语法
在使用jsx的时候,需要注意几个点
在使用jsx的地方,要注意我们的代码不能被JavaScript引擎直接解析,所以要在为script标签设置特殊的type属性, 阻止JavaScript引擎的解析
在jsx中只能有一个根节点,如果存在多个根节点会报错,jsx同时也可以进行标签的嵌套
ReactDOM.render(/*根节点*/, document.querySelector("#root") )hello world
在jsx中,我们虽然写的时候看起来比较像是直接写html,但实际上还是JavaScript,所以需要使用JavaScript的语法,例如我们在为标签添加class属性时,不能写class,而是要使用JavaScript语法的className,这样才能被正确的解析
ReactDOM.render(, document.querySelector("#root") )
同样的其他一些属性也需要转化为驼峰写法,如tabindex 则对应着 tabIndex
在jsx中使用单标签,需要在结尾处使用/>,否则不能够被正确的解析
ReactDOM.render(, document.querySelector("#root") )
在jsx中可以任意的使用JavaScript的表达式,但是需要将表达式放置在{}中
const obj = { name: "tom", age: (age) => { return age; } } ReactDOM.render(, document.querySelector("#root") ) /*编译结果*/ //我是tom,年龄是18,2+2是8,0>1的结果是false我是{obj.name},年龄是{obj.age(18)},2+2是{3 + 5},0>1的结果是{0 > 1 ? "true" : "false"}
由于jsx本身就是JavaScript,所以我们也可以通过条件判断来决定控制模板的内容
const obj = { name: "tom", age: (age) => { return age; } }; function judgment(user) { let component; component = user ?控制样式:我是{obj.name},年龄是{obj.age(18)},2+2是{3 + 5},0>1的结果是{0 > 1 ? "true" : "false"}
出现错误了哦return component; } ReactDOM.render( judgment(true), document.querySelector("#root") )
React中并没有提供其他框架中的例如ng-show、v-if等命令,这些都是需要我们自己手动去写的
控制元素的显示/隐藏
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: "block" } } fn() { this.setState({ flag: this.state.flag == "block" ? "none" : "block" }) } render() { return} } ReactDOM.render(, document.querySelector("#root") )
控制class样式
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: true } } fn() { this.setState({ flag:!this.state.flag }) } render() { return} } ReactDOM.render(是否渲染
, document.querySelector("#root") )
在实际开发中上面的方法都不是很直观,推荐使用classnames库
class Control extends React.Component { constructor(...args) { super(...args); this.state = { flag: false } } fn() { this.setState({ flag:!this.state.flag }) } render() { return组件} } ReactDOM.render(是否渲染
{ this.state.flag ? : null }, document.querySelector("#root") )
组件这个概念现在也是非常流行了,如果之前没有使用过其他框架的话可以用一个相对比较通俗的例子来理解组件的概念,Moto之前推出过好几款模块化的手机,该手机包括屏幕,处理器,内存,电池,摄像头等,都支持自由更换拼装,然后组装成一个完整的手机
, document.querySelector("#root") )
注意,使用组件时,组件名称一定要是大写字母开头的,否则的话会被认为是普通的html文本进行解析,同时也需要注意的是组件内只允许有一个根元素
组件的嵌套在React中,组件之间是可以嵌套使用的
class Hello extends React.Component { render() { return容器类组件hello} } class Wrold extends React.Component { render() { return} } ReactDOM.render(world
, document.querySelector("#root") )
这个概念类似于Vue中的插槽,如果没有Vue知识的可以将这个理解为在在使用某个组件时我们在该组件内插入一些DOM元素,而且要保证这些DOM元素能够被正确渲染
class FancyBorder extends React.Component { render() { return ({this.props.children}) } } ReactDOM.render(, document.querySelector("#root") ) Lorem ipsum dolor sit amet.
Lorem ipsum dolor.
这里就借用一下Vue的概念,我们将组件中设定了{this.props.children} 的部分称为插槽
在需要插入来自调用者的DOM的部分写入{props.children},之后调用者插入的代码就会在我们写入了{props.children}的位置上被展示
我们此时可以打印一下props.children,可以发现得到的是一个数组的结果
, document.querySelector("#root") ) 组件之间的通信
class Child extends React.Component { render() { returnhello {this.props.name}} } class Parent extends React.Component { render() { return} } ReactDOM.render(, document.querySelector("#root") )
props方法时官方提供的接口,我们在使用组件时,在引用子组件处,将要传递的内容以设置属性的方式添加到子组件,在子组件中通过this.props[父组件设置的属性名]的格式就可以获取到父组件传递的信息,通过props可以传递字符串、数字、对象、数组、函数 ,子组件在可以通过this.props来查看当前所有接收到的值
class Child extends React.Component { click(e) { console.log(this.props.data,"child"); e.stopPropagation(); } render() { returnhello {this.props.data.name}} } class Parent extends React.Component { constructor() { super(); this.state = { obj: { name: "tom", age: 18 } } } click() { console.log(this,"parent") } render() { return} } ReactDOM.render(, document.querySelector("#root") )
class Child extends React.Component { render() { return } } class Parent extends React.Component { click(e) { console.log(this) e.stopPropagation() } render() { return} } ReactDOM.render(, document.querySelector("#root") )
传递事件的时候可以通过bind改变我们最初事件的this的指向,这里我们看打印的结果,this的指向在child中指向的是child组件
状态提升这个概念其实可以理解为我们在其他框架中使用的姜子组件的信息传递给父组件的一个过程,但是在react中并没有提供直接的方法,需要我们自己进行处理,实现的代码如下:
class Child extends React.Component { click(i,e) { i++; this.props.P_click(i); e.stopPropagation(); } render() { return} } class Parent extends React.Component { constructor() { super(); this.state = { index: 1 } this.P_Click = this.P_Click.bind(this) } change(data) { this.setState({ index: data }); } render() { return{this.state.index}} } ReactDOM.render(, document.querySelector("#root") )
我们首先来说一下大概的思路
在父组件中设置一个方法change,在该方法中设置改变我们指定的变量值的处理
change(data) { this.setState({ index: data }); }
将该方法传递给子组件,同时也将我们要要改变的父组件的值传递给子组件
在子组件操作时,例如点击时,调用我们在父组件中传入的change方法,并改变由父组件发送过来的数据(index),回传给change方法
click(i,e) { i++; this.props.P_click(i) e.stopPropagation(); }
change方法被调用,通过this.setState响应的改变了父组件中index值
可以看出来确实很麻烦,由于没有像vue那样提供$emit方法,所以需要我们自己迂回写一系列操作,包括如果我们想要在同级的组件之间传递数据,我们需要 子组件数据 => 父组件 => 子组件兄弟组件
推荐使用Redux来进行组件之间的数据传递
响应式的更新数据 生命周期, document.querySelector("#root") )
在执行上诉代码之后,我们会看到一行报错
react.js:369 Warning: Each child in an array or iterator should have a unique "key" prop.Check the render method of Lists.
这是React提示需要在为我们通过遍历渲染的li添加key值,采用如下操作
React是不会去渲染之前已经存在的元素,这也是React的高效性的原因之一,key值可以帮助React识别那些元素发生了变化,那些没有变化,从而使React在渲染时保留那些之前已经被渲染的元素
还是上面的代码,我们打开控制台,在为第一个li添加一个临时的color,然后点击添加按钮,可以发现这个li的样式依然被保持了,说明React没用重新渲染该元素
, document.querySelector("#root") )
然后我们尝试在输入框中输入文字会发现不论输入什么内容,输入框中会依然保持是react,这是因为在我们创建input的时候,value就已经被react劫持了
react也会特别贴心的进行提示
Failed prop type: You provided a value prop to a form field without an onChange handler. This will render a read-only field. If the field should be mutable use defaultValue. Otherwise, set either onChange or readOnly. in input
根据提示,我们可以发现我们需要设置为如下的格式
ReactDOM.render( , document.querySelector("#root") )
这个时候我们就可以正常的修改表单数据了,同样的会被react劫持的还有一个属性,就是checked,在使用时同样需要转换为React提供的defaultChecked
react中是没有双向绑定这个概念的,实际的react其实可以理解为是一个单向的数据绑定,所有的顶层具有的state做为数据流通过props向下传递给子组件,然后在数据改变的时候重新调用render,重而重新渲染页面
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/97299.html
摘要:希望大家在这浮夸的前端圈里,保持冷静,坚持每天花分钟来学习与思考。 今天的React题没有太多的故事…… 半个月前出了248个Vue的知识点,受到很多朋友的关注,都强烈要求再出多些React相前的面试题,受到大家的邀请,我又找了20多个React的使用者,他们给出了328道React的面试题,由我整理好发给大家,同时发布在了前端面试每日3+1的React专题,希望对大家有所帮助,同时大...
摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解,以及在项目中更加灵活地使用React。 React 中的元素、组件、实...
摘要:中的元素组件实例和节点,是中关系密切的个概念,也是很容易让初学者迷惑的个概念。组件和元素关系密切,组件最核心的作用是返回元素。只有组件实例化后,每一个组件实例才有了自己的和,才持有对它的节点和子组件实例的引用。 文:徐超,《React进阶之路》作者授权发布,转载请注明作者及出处 React 深入系列,深入讲解了React中的重点概念、特性和模式等,旨在帮助大家加深对React的理解...
摘要:在前端开发过程中,源码解读是必不可少的一个环节,我们直接进入主题,注意当前版本号。注意包文件仅仅是的必要的功能性的定义,它必须要结合一起使用下是,原生环境下是。 在前端开发过程中,源码解读是必不可少的一个环节,我们直接进入主题,注意当前 React 版本号 16.8.6。 注意:react 包文件仅仅是 React components 的必要的、功能性的定义,它必须要结合 React...
摘要:内部机制探秘和文末附彩蛋和源码这篇文章比较偏基础,但是对入门内部机制和实现原理却至关重要。当然也需要明白一些浅显的内部工作机制。当改变出现时,相比于真实更新虚拟的性能优势非常明显。直到最终,会得到完整的表述树的对象。 React 内部机制探秘 - React Component 和 Element(文末附彩蛋demo和源码) 这篇文章比较偏基础,但是对入门 React 内部机制和实现原...
摘要:本文翻译自原作者如果有任何版权问题,请联系当你在组件中调用时,你觉得会发生什么当然,会用这条状态重新渲染组件并且更新匹配到的,然后返回元素。如果你之前使用过一些渲染器比如说,你可能知道在页面中使用超过一个渲染器是没什么问题的。 本文翻译自:How Does setState Know What to Do?原作者:Dan Abramov 如果有任何版权问题,请联系shuirong199...
阅读 2939·2021-10-27 14:16
阅读 676·2021-10-13 09:39
阅读 3629·2021-09-29 09:46
阅读 2065·2019-08-30 15:54
阅读 2585·2019-08-30 15:52
阅读 2975·2019-08-30 15:44
阅读 1087·2019-08-30 15:44
阅读 484·2019-08-30 10:51