• react基础语法二


      这里只是对自己的学习进行一次总结,也是为了让自己以后如果长时间不使用快速记忆起来的笔记,如果想要学习,还是去官网看文档比较好一些。、

      注意 下面的代码的 script标签的type类型都为 “text/babel”

    目录

    一、无状态组件

    二、函数式声明

    三、this以及事件对象

    四、操作dom元素

    五、父子组件传值

    六、在浏览器中支持import export

    一、 无状态的组件

      只是普通的变量是没有状态的, 只有组件才有状态或无状态

      react是单向数据流

      状态其实就是让数据驱动视图的响应式数据

     1 let a = '这里是div元素111';
     2 
     3 setTimeout(() => {
     4   console.log('函数执行了');
     5   a = '改变之后的值'
     6 },2000);
     7 
     8 const element = (
     9   <div>{a}</div>
    10 );
    11 
    12 ReactDOM.render(
    13   element,
    14   document.getElementById('app')
    15 )

    如果你学习过vue的话,那种双向数据绑定用的 Object.defineProperty() 叫数据劫持,然后用了订阅发布(观察者)那种模式,数据改变之后,会驱动着视图去改变

    react必须要通过 setState() 这个组件的实例化对象去调用去改变自身的state才会去驱动视图是改变的,所以上面的那种就算数据改变了,但是视图是没有进行改变的。

    看下面的es6的这种写法

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4     this.state = { // 只有在state里面的内容才是有无状态的
     5       a: '这里是div元素'
     6     };
     7 
     8     setTimeout(() => {
     9       this.setState({  // 这里必要要用 setState这个方法来改变值才会驱动视图去改变  如果  this.state.a = 'sdfsd' 这样是不会驱动视图去改变的
    10         a: '改变之后的值'
    11       })
    12     }, 1000)
    13   }
    14   render() {
    15     return (
    16       <div>
    17         {this.state.a}
    18       </div>
    19     );
    20   }
    21 }
    22 
    23 ReactDOM.render(
    24   <Element/>,
    25   document.getElementById('app')
    26 )

    二、 函数式声明

      其实之前一直都是使用的变量去指代html元素,没有使用过 class 那种,现在先使用ES5的写法去写一写什么是函数式声明。

      先看一下之前的写法吧

     1 const Head = (
     2   <h2>Head头部</h2>
     3 );
     4 const Foot = (
     5   <h2>底部</h2>
     6 );
     7 const element = (
     8   <div>
     9     {
    10       Head
    11     }
    12     <h2>Element内容</h2>
    13     {
    14       Foot
    15     }
    16   </div>
    17 );
    18 
    19 ReactDOM.render(
    20   element,
    21   document.getElementById('app')
    22 )

    函数式声明是什么样子的呢

     1 const Head = function () {
     2   return (
     3     <h2>Head头部</h2>
     4   )
     5 };
     6 const Foot = function () {
     7   return (
     8     <h2>底部</h2>
     9   )
    10 };
    11 const Element = function() {
    12   return (
    13     <div>
    14       <Head/>
    15       <h2>Element内容</h2>
    16       <Foot/>
    17     </div>
    18   );
    19 };
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    可以很清晰的看到他们两个的区别,一个是使用变量来代表的,另外的一个是使用的组件形式代表的,开发中的写法都是使用ES6的class继承声明来写组件的

    看一下函数声明的传值

     1 const Head = function (props) {
     2   return (
     3     <h2>{props.title}</h2>
     4   )
     5 };
     6 const Foot = function (props) {
     7   return (
     8     <h2>{props.con}</h2>
     9   )
    10 };
    11 const Element = function() {
    12   return (
    13     <div>
    14       <Head
    15         title={'头部信息啊'}
    16       />
    17       <h2>Element内容</h2>
    18       <Foot
    19         con={'底部的内容啊'}
    20       />
    21     </div>
    22   );
    23 };
    24 
    25 ReactDOM.render(
    26   <Element></Element>,
    27   document.getElementById('app')
    28 )

    这个样子和vue其实是挺像的,在标签上面写自定义的属性,子组件就可以接收到,等先这样看看,后面会使用class写的,class写起来感觉还容易理解一些。

    注意: 函数式声明组件

      1. 组件的首字母必须是大写

      2. 不要使用H5新标签

    下面看一个状态改变驱动视图的例子

     1 const Head = function (props) {
     2   return (
     3     <h2>{props.title}</h2>
     4   )
     5 };
     6 const Foot = function (props) {
     7   return (
     8     <h2>{props.con}</h2>
     9   )
    10 };
    11 
    12 class Element extends React.Component{
    13   constructor() {
    14     super();
    15     this.state = {
    16       title: '头部信息',
    17       con: '底部信息'
    18     };
    19 
    20     setTimeout(() => {
    21       this.setState({
    22         title: '头部信息改变'
    23       })
    24     },2000)
    25   }
    26   render() {
    27     return (
    28       <div>
    29         <Head
    30           title={this.state.title}
    31         />
    32         <h2>Element内容</h2>
    33         <Foot
    34           con={this.state.con}
    35         />
    36       </div>
    37     );
    38   }
    39 }
    40 
    41 ReactDOM.render(
    42   <Element></Element>,
    43   document.getElementById('app')
    44 )

    这样就可以和上面那种结合起来了,以后所有的组件都用class来写了,就不用function那种形式了。

    三、 this以及事件对象

      react组件中的this和事件对象的不同写法有的写法是需要绑定this的

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4   }
     5 
     6   btn() {
     7     console.log(this);  // 可以看到这里打印的是 undefined
     8   }
     9 
    10   render() {
    11     return (
    12       <div>
    13        <h1>title</h1>
    14         <button onClick={this.btn}>按钮</button>
    15       </div>
    16     );
    17   }
    18 }
    19 
    20 ReactDOM.render(
    21   <Element></Element>,
    22   document.getElementById('app')
    23 )

    看到上面打印的this是undefined,下面有几种写法可以更正this指向实例化对象的

    第一种 更正this和事件对象

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4     this.btn = this.btn.bind(this);  // 在这里更正,官方推荐的也是这种写法
     5   }
     6 
     7   btn(e) {
     8     console.log(this);
     9     console.log(e.target)
    10   }
    11 
    12   render() {
    13     return (
    14       <div>
    15        <h1>title</h1>
    16         <button onClick={this.btn}>按钮</button>
    17       </div>
    18     );
    19   }
    20 }
    21 
    22 ReactDOM.render(
    23   <Element></Element>,
    24   document.getElementById('app')
    25 )

    需要注意的是上面的那种写法如果传递参数的话,那么事件对象就是最后一个没有对象参数的和js中的bind一样

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4     this.btn = this.btn.bind(this);  // 在这里更正,官方推荐的也是这种写法
     5   }
     6 
     7   btn() {
     8     console.log(this);
     9     console.log(arguments)  // 因为下面的函数传递了参数,这里第二个参数才是事件对象
    10   }
    11 
    12   render() {
    13     return (
    14       <div>
    15        <h1>title</h1>
    16         <button onClick={this.btn(1)}>按钮</button>
    17       </div>
    18     );
    19   }
    20 }
    21 
    22 ReactDOM.render(
    23   <Element></Element>,
    24   document.getElementById('app')
    25 )

    第二种 在行内bind

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4   }
     5 
     6   btn() {
     7     console.log(this);
     8     console.log(arguments)
     9   }
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1>title</h1>
    15         <button onClick={this.btn.bind(this, 1)}>按钮</button>  // 直接写到行内,在这里改变this的指向,同样的问题,那个参数的事件对象是最后一个
    16       </div>
    17     );
    18   }
    19 }
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    第三种 在一个函数里面执行它

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4   }
     5 
     6   btn(e) {
     7     console.log(this);
     8     console.log(arguments)
     9   }
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1>title</h1>
    15         <button onClick={(e) => {
    16           this.btn(e,11);
    17         }}>按钮</button>
    18       </div>
    19     );
    20   }
    21 }
    22 
    23 ReactDOM.render(
    24   <Element></Element>,
    25   document.getElementById('app')
    26 )

    第四种 改变函数的写法

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4   }
     5 
     6   btn = (e) => {
     7     console.log(this);
     8     console.log(e.target)
     9   }
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1>title</h1>
    15         <button onClick={this.btn}>按钮</button>
    16       </div>
    17     );
    18   }
    19 }
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    当然了这种方式如果要传递参数的话还是需要bind的。

    四、 操作dom元素

      如果想要在react中操作dom元素的话,有几种方法

    第一种 直接使用js的方法

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4 
     5   }
     6 
     7   btn = () => {
     8     const ele = document.querySelector('.h1');
     9     console.log(ele);
    10 
    11   };
    12 
    13   render() {
    14     return (
    15       <div>
    16        <h1 className='h1'>title</h1>
    17         <button onClick={this.btn}>按钮</button>
    18       </div>
    19     );
    20   }
    21 }
    22 
    23 ReactDOM.render(
    24   <Element></Element>,
    25   document.getElementById('app')
    26 )

    第二种 通过事件对象

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4 
     5   }
     6 
     7   btn = (e) => {
     8     console.log(e.target);
     9   };
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1 className='h1'>title</h1>
    15         <button onClick={this.btn}>按钮</button>
    16       </div>
    17     );
    18   }
    19 }
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    第三种 ref

      和vue一样

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4 
     5   }
     6 
     7   btn = (e) => {
     8     console.log(this.refs.abc)  // 在这里获取它
     9   };
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1 ref="abc">title</h1>  // 这里定义一个字符串的名字
    15         <button onClick={this.btn}>按钮</button>
    16       </div>
    17     );
    18   }
    19 }
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    不过最新版本的不建议上面的那种写法了,也是ref建议下面的写法

    以后我们就可以用下面这种最常用的方式

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4 
     5   }
     6 
     7   btn = (e) => {
     8     console.log(this.abc)
     9   };
    10 
    11   render() {
    12     return (
    13       <div>
    14        <h1 ref={abc => {this.abc = abc}}>title</h1>
    15         <button onClick={this.btn}>按钮</button>
    16       </div>
    17     );
    18   }
    19 }
    20 
    21 ReactDOM.render(
    22   <Element></Element>,
    23   document.getElementById('app')
    24 )

    第四种 ReactDOM.findDOMNode

     1 class Element extends React.Component{
     2   constructor() {
     3     super();
     4 
     5   }
     6 
     7   btn = (e) => {
     8     console.log(this.abc)
     9 
    10     console.log(ReactDOM.findDOMNode(this.abc));
    11   };
    12 
    13   render() {
    14     return (
    15       <div>
    16        <h1 ref={abc => {this.abc = abc}}>title</h1>
    17         <button onClick={this.btn}>按钮</button>
    18       </div>
    19     );
    20   }
    21 }
    22 
    23 ReactDOM.render(
    24   <Element></Element>,
    25   document.getElementById('app')
    26 )

    ref如果标记的是组件,那么ref他就是组件,但是findDOMNode这种方式是获取DOM元素的,就算里面的参数是组件,也是获得DOM元素

    五、 父子组件传值

      核心思想 

      父组件给子组件传值 直接在组件上面添加属性就可以了 子组件通过props访问,得到 其实是构造函数实例化的时候传过去了

      子组件给父组件传值 其实是父组件给子组件传一个函数,子组件调用的时候把 要传递的数据 放到 父组件传递过来的函数 的参数里面,然后父组件再去做他自己的操作

    Item子组件


    1
    class Item extends React.Component { 2 constructor (props) { 3 super(props); 4 this.state = { 5 sub: this.props.data 6 } 7 } 8 9 componentWillReceiveProps(nextProps) { 10 console.log('执行了吗'); 11 console.log(nextProps); 12 } 13 14 render() { 15 console.log('子组件打印this'); 16 console.log(this); 17 console.log(this.props); 18 19 return ( 20 <div> 21 <p>Item组件</p> 22 <h1>{this.state.sub.res}</h1> 23 <input type="button" defaultValue="这里" onClick={this.props.supFn.bind(this,'子组件参数')} /> 24 <input type="button" 25 defaultValue="22" 26 onClick={() => { 27 this.props.supFn('参数2') 28 }} 29 30 /> 31 </div> 32 ); 33 } 34 }

    父组件

     1 class Main extends React.Component {
     2   constructor() {
     3     super();
     4     this.superFn = this.superFn.bind(this);
     5 
     6   }
     7   state = {
     8     data: {
     9       res: '里面的数据'
    10     }
    11   };
    12 
    13   superFn(a) {
    14     console.log('父组件的函数');
    15     console.log(`${a}`);
    16     let data = {
    17         res: '修改过后'
    18     };
    19     console.log(data);
    20 
    21     this.setState({
    22       data: data
    23     })
    24   }
    25   render() {
    26     return (
    27       <div>
    28         <p>主页面</p>
    29           <p>{this.state.data.res}</p>
    30         <Item supFn={this.superFn} data={this.state.data} aaa="传值啊"></Item>
    31       </div>
    32     );
    33   }
    34 }
    35 
    36 ReactDOM.render(
    37   <Main />,
    38   document.getElementById('app')
    39 )

    六、在浏览器中支持import export

      要在服务器环境下打开文件

      在谷歌浏览器输入框中输入

    然后就可以使用模块导出导出功能了

    1 // 2.js
    2 const a = 1;
    3 const b = 2;
    4 
    5 export default {a, b};
    1 <script type="module">
    2     // 要服务器环境下打开  http服务
    3     // chrome//flags 开启那个权限
    4     import a from './2.js';
    5     console.log(a)
    6 </script>

    如果你看了我的文章有了一些收获我会非常高兴的,由于能力有限,文章有的部分解释的不到位,希望在以后的日子里能慢慢提高自己能力,如果不足之处,还望指正。

  • 相关阅读:
    作用域面试题
    js··BOM 浏览器对象模型
    js···DOM2动态创建节点
    js ·节点的知识点
    js·逻辑运算
    js···元素的属性
    什么是函数封装。
    hive 历史拉链表的处理
    [转]实现Hive数据同步更新的shell脚本
    python 3 过滤股票
  • 原文地址:https://www.cnblogs.com/z937741304/p/10165206.html
Copyright © 2020-2023  润新知