啦啦啦,今天开始就要正式开始个人react之路了,首先我用了create-react-app命令工具快速建了一个react项目,既然是从0到1,我就给src里面的内容删的干干净净。 写了一个最简单的:html
//index.js
// 导入的React必须大写
import React from 'react';
import ReactDom from 'react-dom';
const h1 = <h1>hello world</h1>; //会用babel进行转化 转化成React.createElement写法
// 是语法糖
ReactDom.render(h1,window.root)
复制代码
问题1: 为何必须React大写?vue
问题2: reader咋实现的?node
先来讲问题一: 原来啊 jsx语法配合babel编译 而后调用React.createElement 那就本身写一个吧react
let React = {
createElement(type,props,...children){
return {
type,props,children
}
}
}
复制代码
问题2:render实现面试
// 固然这个render方法只是描述render最终干吗了,实际在render中要远比这复杂,涉及到dom diff
let render = (vnode,container) => {
if(typeof vnode == 'string') return container.appendChild(document.createTextNode(vnode));
let {type,props,children} = vnode;
let ele = document.createElement(type);
for(let key in props) {
ele.setAttribut(key,props[key]);
}
children.forEach((child)=>{
render(child,ele)
})
container.appendChild(ele);
}
复制代码
接下来咱们稍微复杂一点 渲染多个元素: 须要注意的是多个元素须要被一个标签包裹起来,我通常是数组
let ele = (
<> <h1>你好</h1> <span>哈哈</span> </> ) 复制代码
上面只是简单的介绍,那jsx语法有如下这些规则:babel
若是渲染两个相邻的jsx元素 须要被外面的一个标签所包裹 <></>app
行内样式的写法, jsx为了识别是html仍是js 须要用 < { 来区分dom
{} 表示的是写js 三元表达式,取值 ,(只要内容有返回值就能够显示)函数
属性的名字有变化 htmlFor => for / className=> class;
像v-html 把内容当成html 插入到页面中 dangerouslySetInnerHTML
注释只能写js注释
{/*当前是一个危险的操做 */}
<div dangerouslySetInnerHTML={{__html:str}}></div>
复制代码
let arr = ['吃饭', '喝水', '睡觉']
let eleArr = arr.map((item) => {
<li>{item}</li>
})
ReactDOM.render(eleArr,window.root)
复制代码
let arr = ['吃饭', '喝水', '睡觉']
let eleArr = arr.map((item) => {
<li>{item}</li>
})
let obj = (
<ul>
{eleArr}
</ul>
)
复制代码
以上就是jsx的基本用法,可是一个项目会很复杂,咱们经常会封装不少组件,这样便于复用和维护,人家react文档中说了,在react中,一个函数就是一个组件。
在react中 组件名必须大写,和jsx,react元素进行区分
import React from 'react';
import ReactDom from 'react-dom';
function Clock() {
return (<h1>当前时间</h1>)
}
ReactDom.render(<Clock></Clock>,window.root)
//或者这样 还能够和jsx嵌套
//ReactDom.render(<div><Clock></Clock></div>,window.root)
复制代码
其实在react中有两类组件: 全部组件都有属性
函数组件属性的用法:
function Clock(props) {
return (<h1>当前时间:props.date.toLocaleString()</h1>)
}
ReactDom.render(<Clock date={new Date()}></Clock>,window.root)
复制代码
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父类 提供更改状态的 setState方法
class Clock extends Component{
<!--constructor(props) {-->
<!-- super(props) //Component.call(this,props)--> <!-- this.state = {}--> <!--}--> state = { //es7 date: new Date().toLocaleString() } render(){ return <h1>时间是:{this.state.date}</h1> } } ReactDom.render(<Clock></Clock>,window.root) 复制代码
接下来咱们了解一个很是重要的概念 生命周期 和vue同样 像上面的时钟案例,咱们须要让时钟走动,最low的方法就是不断的render,也有用更改状态setState方法,可是何时去执行呢,这里就涉及到生命周期的问题了
import React, {Component} from 'react'
import ReactDom from 'react-dom'
//React.Component 父类 提供更改状态的 setState方法
class Clock extends Component{
state = { //es7
date: new Date().toLocaleString()
}
handleClick = () => { //妥善处理好了this指向问题
console.log(this)
}
componentDidMount() {
setInterval(() => {
this.setState({ //只会改动你要改动的,并不会干掉你没有要改动的
date: new Date().toLocaleString()
})
},1000)
}
render(){
return <h1>时间是:{this.state.date} <span onClick={this.handleClick}>点击</span></h1>
}
}
ReactDom.render(<Clock></Clock>,window.root)
复制代码
这里留一个经典面试题: setState 批量更新 只针对同一个属性变量 不一样的属性变量没有这个问题
解决方法:
1)setTimeout() 不推荐 2)prevState
this.setState((prevState) => {
count: prevState.count+1
})
//等价下面
this.setState({
count:this.state.count+1
},() => {
<!--在下一个state操做-->
})
复制代码
总结一下:
import React, {Component} from 'react';
import ReactDom from 'react-dom'
class Count extends Component{
constructor() {
super()
}
state = {
}
render(){
return (
<div> </div>
)
}
}
ReactDom.render(<Count></Count>,window.root)
复制代码
{this.props.xxx}
{this.state.xxx}
复制代码
以上是本身学习入门React的入门笔记,分享给你们,固然还有不少不足之处但愿你们指出,我会继续再接再砺更深刻的从一到二