前端学习周记(4)——浅谈渲染DOM

看了书,发现自己能看懂一部分,但是自己不会实现啊……
然后又投入到B站的学习中,解锁新技能——在B站学react……

这周想先谈谈DOM,如果时间允许会再多写一点。
首先,还是解决第一个问题,什么是DOM,为什么要谈谈DOM呢?

↑这是百度百科的解释,当然,这不是我们要谈及的(显然是看不懂百度百科的托词,勿怪勿怪)所谓模型呢,就像一种结构,一种规定,这样类似的东西。

至于为什么要谈,因为要用啊┐(・o・)┌ 

当然这里只是简单放上渲染DOM的例子(一开始听的那些说不用虚拟DOM的方法……抱歉我还真的不会,不过单单从代码的复杂度来看确实是简单了,然而我还是没看懂不用虚拟DOM怎么操作)
顺便,谨以此文庆祝我终于渲染成功了……
想必大家对刚刚看到react的时候要下载的那几个文档还有映像(我也是最近才明白一点的……所以我为啥不早早看B站,非要自己折腾……)

(好了,这里先存一下中文react官网的网址 https://doc.react-china.org/
顺便值得一提的是,发现那个文档可能有的浏览器按Ctrl+S没法保存,这个时候就要暴力出奇迹了,比如直接放记事本,然后手动改文件后缀名为.js

*************************基本内容**************************

<!DOCTYPE html><html> <head> <meta charset="UTF-8" /> <title>test</title> <script src="https://unpkg.com/react@16/umd/react.development.js"></script> <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script> </head> <body> <div id="root"></div> <script type="text/babel">var myStyle = { fontSize: 100, color: '#FF0000'};var i=1
//渲染DOMReactDOM.render( <div> <h1 style={myStyle}>{i==1?'true':'false'}</h1> </div> , document.getElementById('root') ); </script> </body></html>

这里没有使用本地的那几个文件是为了方便大家直接打开也没有问题ヾ(◍°∇°◍)ノ゙
效果如下图:

昨晚不知道为啥,一直都渲染不出来,今天早上才发现是文件的位置记错了……果然我不适合晚上写代码……
再放一个例子,有关数组的(这里再强调一下,要加分号,要加分号,要加分号……)
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
	const names=['a','b','c','d','e','f'];
	ReactDOM.render(
      	<div>
		{names}
        </div>
      	,
      	document.getElementById('root')
      );
    </script>
  </body>
</html>

-------------------------歪楼-----------------------------------
有关注释:
1、在标签内部的注释需要花括号

2、在标签外的的注释不能使用花括号

ReactDOM.render(
    /*注释 */
    <h1>test{/*注释*/}</h1>,
    document.getElementById('example')
);

-----------------------------------------------------------------
好了,下面放的例子就是可以随意调皮的地方了\(*ΦωΦ)ノ
用习惯了html里面仅有的几个标签,这一说可以皮还真有些不习惯(看来我天生就是好宝宝……)
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="example"></div>
    <script type="text/babel">
      const Corn = React.createClass({
        render: function() {
          return <h1>Hello World!</h1>;
        }
      });

      ReactDOM.render(
        <Corn />,
        document.getElementById('example')
      );
    </script>
  </body>
</html>

这里要注意皮归皮,但是标签是有要求的,就是首字母大写
原生 HTML 元素名以小写字母开头,而自定义的 React 类名以大写字母开头,比如 Corn 不能写成 corn。除此之外还需要注意组件类只能包含一个顶层标签,否则也会报错。
如果我们需要向组件传递参数,可以使用  this.props  对象(哦,忘了说了,听说this是组件对象,什么是组件对象呢?管那么多干什么,就不能让我专心写完渲染DOM吗)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
    var Corn = React.createClass({
  		render: function() {
    		return <h1>Hello {this.props.name}</h1>;
			/*诺,就像这样,这里的{this.props.name}就是表示把下面的WiFi放到这里来*/
  		}
	});
 
	ReactDOM.render(
  	<Corn name="WiFi" />,
  	document.getElementById('root')
	);
    </script>
  </body>
</html>
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
    var Corn = React.createClass({
  		render: function() {
		/*或者我们也可以直接放{this.props.name},不过值得关注的是,我们只能放大括号,如果变成引号……大家看下面的两个对比*、
    		return <h1>{this.props.name}</h1>;
			/*诺,就像这样,这里的{this.props.name}就是表示把下面的WiFi放到这里来*/
  		}
	});
 
	ReactDOM.render(
  	<Corn name="WiFi" />,
  	document.getElementById('root')
	);
    </script>
  </body>
</html>

vs <-这里是有张图片的,看不到就对了,因为没有结果……


<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
 /*还是一个叫Corn的标签,里面再放两个*/
    var Corn = React.createClass({
     render: function() {
      return (
         <div>
    /*里面再放两个标签(所谓复合)*/
          <Name name={this.props.name} />
          <Link site={this.props.site} />
         </div>
      );
    }
 });
 /*名字创建在这里*/
 var Name = React.createClass({
    render: function() {
      return (
         <h1>{this.props.name}</h1>
      );
    }
 });
 /*链接创建在这里*/
 var Link = React.createClass({
    render: function() {
      return (
         <a href={this.props.site}>
          {this.props.site}
        </a>
      );
    }
 });
 /*渲染啦啦啦*/
 ReactDOM.render(
    <Corn name="bable" site=" http://babeljs.io/" />,
    document.getElementById('root')
 );
    </script>
  </body>
</html>

-----》反正格式就是:

<body>
    <div id="a"></div>
    <script type="text/babel">
//创建
      var C1 = React.createClass({
        render: function() {
          return <h1>Hello World!</h1>;
        }
      });
//渲染
      ReactDOM.render(
        <C1 />,
        document.getElementById('a')
      );
    </script>
  </body>


a:随便取个id啦
C1:标签首字母大写
return <h1>Hello World!</h1>;
这一句随便是直接return还是再塞两个标签

***********************************************************

*************************添加交互**************************

这个差不多了,懒得手打……
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="test"></div>
    <script type="text/babel">
      var Corn = React.createClass({
        getInitialState: function() {
		//相当于一个bool
          return {liked: false};
        },
		//取反
        handleClick: function(event) {
          this.setState({liked: !this.state.liked});
        },
		//注意哈,还在那个创建类里面
		//折腾了一个变量text,估计是为了省事
        render: function() {
          var text = this.state.liked ? '喜欢' : '不喜欢';
          return (
		  //点击
            <p onClick={this.handleClick}>
              你<b>{text}</b>我。
            </p>
          );
        }
      });
//渲染
      ReactDOM.render(
        <Corn />,
        document.getElementById('test')
      );
    </script>
  </body>
</html>

说了这么多,大家是否注意到了一个关于this的问题—— this . props . namethis . state . name

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
      var Corn = React.createClass({
        render: function() {
          return <h1>Hello {this.props.name}</h1>;
        }
      });

      ReactDOM.render(
        <Corn name="WiFi" />,
        document.getElementById('root')
      );
    </script>
  </body>
</html>

若换做state则又会没有任何作用……

可以通过 getDefaultProps() 方法为 props 设置默认值,实例如下:

React 实例

var HelloMessage = React . createClass ( {
 
getDefaultProps : function ( ) {
   
return {
     
name : ' Runoob '
   
} ;
 
} ,
 
render : function ( ) {
   
return < h1 > Hello { this . props . name } </ h1 >;
 
}
} ) ;

ReactDOM . render (
  <
HelloMessage />,
 
document . getElementById ( ' example ' )
) ;
诺,混合使用的例子(好像上面举过例子了……算了,不记得了)
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
    var Corn = React.createClass({
      getInitialState: function() {
        return {
          name: "bable",
          site: "http://babeljs.io/"
        };
      },
     
      render: function() {
        return (
          <div>
            <Name name={this.state.name} />
            <Link site={this.state.site} />
          </div>
        );
      }
    });

    var Name = React.createClass({
      render: function() {
        return (
          <h1>{this.props.name}</h1>
        );
      }
    });

    var Link = React.createClass({
      render: function() {
        return (
          <a href={this.props.site}>
            {this.props.site}
          </a>
        );
      }
    });

    ReactDOM.render(
      <Corn />,
      document.getElementById('root')
    );
    </script>
  </body>
</html>

记得上面关于喜不喜欢的例子吗?那里就用到了设置状态这样的
-----------------------具体直接放别人写的吧--------------------------


设置状态:setState

setState(object nextState[, function callback])

参数说明

  • nextState,将要设置的新状态,该状态会和当前的state合并
  • callback,可选参数,回调函数。该函数会在setState设置成功,且组件重新渲染后调用。

合并nextState和当前state,并重新渲染组件。setState是React事件处理函数中和请求回调函数中触发UI更新的主要方法。

关于setState

不能在组件内部通过this.state修改状态,因为该状态会在调用setState()后被替换。

setState()并不会立即改变this.state,而是创建一个即将处理的state。setState()并不一定是同步的,为了提升性能React会批量执行state和DOM渲染。

setState()总是会触发一次组件重绘,除非在shouldComponentUpdate()中实现了一些条件渲染逻辑。

实例

React 实例

var Counter = React . createClass ( {
 
getInitialState : function ( ) {
   
return { clickCount : 0 } ;
 
} ,
 
handleClick : function ( ) {
   
this . setState ( function ( state ) {
     
return { clickCount : state . clickCount + 1 } ;
   
} ) ;
 
} ,
 
render : function ( ) {
   
return ( < h2 onClick = { this . handleClick } >点我!点击次数为: { this . state . clickCount } </ h2 > ) ;
 
}
} ) ;
ReactDOM . render (
  <
Counter />,
 
document . getElementById ( ' message ' )
) ;

尝试一下 »

实例中通过点击 h2 标签来使得点击计数器加 1。


替换状态:replaceState

replaceState(object nextState[, function callback])
  • nextState,将要设置的新状态,该状态会替换当前的state
  • callback,可选参数,回调函数。该函数会在replaceState设置成功,且组件重新渲染后调用。

replaceState()方法与setState()类似,但是方法只会保留nextState中状态,原state不在nextState中的状态都会被删除。


设置属性:setProps

setProps(object nextProps[, function callback])
  • nextProps,将要设置的新属性,该状态会和当前的props合并
  • callback,可选参数,回调函数。该函数会在setProps设置成功,且组件重新渲染后调用。

设置组件属性,并重新渲染组件。

props相当于组件的数据流,它总是会从父组件向下传递至所有的子组件中。当和一个外部的JavaScript应用集成时,我们可能会需要向组件传递数据或通知React.render()组件需要重新渲染,可以使用setProps()

更新组件,我可以在节点上再次调用React.render(),也可以通过setProps()方法改变组件属性,触发组件重新渲染。


替换属性:replaceProps

replaceProps(object nextProps[, function callback])
  • nextProps,将要设置的新属性,该属性会替换当前的props
  • callback,可选参数,回调函数。该函数会在replaceProps设置成功,且组件重新渲染后调用。

replaceProps()方法与setProps类似,但它会删除原有 props。


强制更新:forceUpdate

forceUpdate([function callback])

参数说明

  • callback,可选参数,回调函数。该函数会在组件render()方法调用后调用。

forceUpdate()方法会使组件调用自身的render()方法重新渲染组件,组件的子组件也会调用自己的render()。但是,组件重新渲染时,依然会读取this.props和this.state,如果状态没有改变,那么React只会更新DOM。

forceUpdate()方法适用于this.props和this.state之外的组件重绘(如:修改了this.state后),通过该方法通知React需要调用render()

一般来说,应该尽量避免使用forceUpdate(),而仅从this.props和this.state中读取状态并由React触发render()调用。


获取DOM节点:findDOMNode

DOMElement findDOMNode()
  • 返回值:DOM元素DOMElement

如果组件已经挂载到DOM中,该方法返回对应的本地浏览器 DOM 元素。当render返回null 或 false时,this.findDOMNode()也会返回null。从DOM 中读取值的时候,该方法很有用,如:获取表单字段的值和做一些 DOM 操作。


判断组件挂载状态:isMounted

bool isMounted()
  • 返回值:truefalse,表示组件是否已挂载到DOM中

isMounted()方法用于判断组件是否已挂载到DOM中。可以使用该方法保证了 setState()forceUpdate()在异步场景下的调用不会出错。
-----------http://www.runoob.com/react/react-component-api.html-----------------

组件的生命周期可分成三个状态:

  • Mounting:已插入真实 DOM
  • Updating:正在被重新渲染
  • Unmounting:已移出真实 DOM

生命周期的方法有:

  • componentWillMount 在渲染前调用,在客户端也在服务端。

  • componentDidMount : 在第一次渲染后调用,只在客户端。之后组件已经生成了对应的DOM结构,可以通过this.getDOMNode()来进行访问。 如果你想和其他JavaScript框架一起使用,可以在这个方法中调用setTimeout, setInterval或者发送AJAX请求等操作(防止异部操作阻塞UI)。

  • componentWillReceiveProps 在组件接收到一个新的 prop (更新后)时被调用。这个方法在初始化render时不会被调用。

  • shouldComponentUpdate 返回一个布尔值。在组件接收到新的props或者state时被调用。在初始化时或者使用forceUpdate时不被调用。 
    可以在你确认不需要更新组件时使用。

  • componentWillUpdate在组件接收到新的props或者state但还没有render时被调用。在初始化时不会被调用。

  • componentDidUpdate 在组件完成更新后立即调用。在初始化时不会被调用。

  • componentWillUnmount在组件从 DOM 中移除的时候立刻被调用。

这些方法的详细说明,可以参考 官方文档




在实例中我们设置了输入框 input 值 value = {this.state.data} 。在输入框值发生变化时我们可以更新 state。我们可以使用  onChange  事件来监听 input 的变化,并修改 state。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
	<script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
	<script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
    var Corn = React.createClass({
      getInitialState: function() {
	  //初始值
        return {value: 'Hello WiFi!'};
      },
	  //改变 监听
      handleChange: function(event) {
        this.setState({value: event.target.value});
      },
      render: function() {
        var value = this.state.value;
        return <div>
		{/*这里就到了html里面的input标签了*/}
                <input type="text" value={value} onChange={this.handleChange} /> 
                <h4>{value}</h4>
               </div>;
      }
    });
    ReactDOM.render(
      <Corn />,
      document.getElementById('root')
    );
    </script>
  </body>
</html>

如何在子组件上使用表单。 onChange 方法将触发 state 的更新并将更新的值传递到子组件的输入框的 value 上来重新渲染界面。

你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>test</title>
    <script src="https://cdn.bootcss.com/react/15.4.2/react.min.js"></script>
 <script src="https://cdn.bootcss.com/react/15.4.2/react-dom.min.js"></script>
 <script src="https://cdn.bootcss.com/babel-standalone/6.22.1/babel.min.js"></script>
  </head>
  <body>
    <div id="root"></div>
    <script type="text/babel">
    var Content = React.createClass({
      render: function() {
        return  <div>
                <input type="text" value={this.props.myDataProp} onChange={this.props.updateStateProp} /> 
                <h4>{this.props.myDataProp}</h4>
                </div>;
      }
    });
    var Corn = React.createClass({
      getInitialState: function() {
        return {value: 'Hello WiFi!'};
      },
      handleChange: function(event) {
        this.setState({value: event.target.value});
      },
      render: function() {
        var value = this.state.value;
        return <div>
                <Content myDataProp = {value} 
                  updateStateProp = {this.handleChange}></Content>
               </div>;
      }
    });
    ReactDOM.render(
      <Corn />,
      document.getElementById('root')
    );
    </script>
  </body>
</html>

-----------------------具体直接放别人写的吧--------------------------

React 事件

以下实例演示通过 onClick 事件来修改数据:

React 实例

var HelloMessage = React . createClass ( {
 
getInitialState : function ( ) {
   
return { value : ' Hello Runoob! ' } ;
 
} ,
 
handleChange : function ( event ) {
   
this . setState ( { value : ' 菜鸟教程 ' } )
 
} ,
 
render : function ( ) {
   
var value = this . state . value ;
   
return < div >
            <
button onClick = { this . handleChange } >点我</ button >
            <
h4 > { value } </ h4 >
           </
div >;
 
}
} ) ;
ReactDOM . render (
  <
HelloMessage />,
 
document . getElementById ( ' example ' )
) ;

当你需要从子组件中更新父组件的 state 时,你需要在父组件通过创建事件句柄 (handleChange) ,并作为 prop (updateStateProp) 传递到你的子组件上。实例如下:

React 实例

var Content = React . createClass ( {
 
render : function ( ) {
   
return   < div >
              <
button onClick = { this . props . updateStateProp } >点我</ button >
              <
h4 > { this . props . myDataProp } </ h4 >
           </
div >
 
}
} ) ;
var HelloMessage = React . createClass ( {
 
getInitialState : function ( ) {
   
return { value : ' Hello Runoob! ' } ;
 
} ,
 
handleChange : function ( event ) {
   
this . setState ( { value : ' 菜鸟教程 ' } )
 
} ,
 
render : function ( ) {
   
var value = this . state . value ;
   
return < div >
            <
Content myDataProp = { value }
             
updateStateProp = { this . handleChange } ></ Content >
           </
div >;
 
}
} ) ;
ReactDOM . render (
  <
HelloMessage />,
 
document . getElementById ( ' example ' )
) ;

----------------http://www.runoob.com/react/react-forms-events.html----------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值