你的簡單不簡單,你的困難真的難
公司專案進,時間週期不夠,個人感覺腳手架真的是個入門直接開發的快速選擇,
搭建環境
首先需要安裝node環境 略
npm install -g creat-react-app//全域性安裝腳手架,任何地方都可以隨時建立專案
create reactApp//建立一個reactApp目錄 並將有所依賴以及配置檔案放入
cd reactApp//進入目錄
npm start//啟動專案
複製程式碼
你已經成功啟動了一個react專案。
React主要核心庫
import React from `react`;
import ReactDom from `react-dom`;
ReactDom.render(
<h1>hello</h1>,
document.getElementById(`root`)
)
複製程式碼
最早的版本,react和react-dom這倆個是放在一起的,後來因為各種架構的優點,互補互惠。將react-dom給拆分出來,react相當於庫的核心,其他的衍生的react庫都如同女朋友一樣偎在他身邊。可以隨時更換隨時使用。
這些太low了,直接講原始碼,
let objMale = <div>hello</divh1>; 等價於 React.createElement(`div`,null,[`hello`]);
js都是可以巢狀的,react當然也可以
let objFemale = <div>hello<span>juejin</span> 等價於 React.createElement(`div`,null,[React.createElement(`span`,null,[`juejin`])]);
console.log(objMale);
複製程式碼
為什麼呢,這裡需要一個圖來解釋一下,
就是這麼簡單(科普一下為什麼外層render下面只能有一個單一根節點,並不是收到jsx的限制,而是因為每個被react渲染的元素都會是一個返回值)
let obj = <div>hello</div>//這裡最終是會return React.createElement(`div`,null,[`hello`]);
如果我在 元件類中 render(){
return (
<div>1</div>
<div>2</div>
)
}
並不是說這不合法,而是因為走到第一個div的時候就已經直接return 出結果,不會向下繼續執行。--知識點哦
複製程式碼
現在開始,我們們先來了解一下最簡單的render方法
剛才列印出來的objMale,你會發現在控制檯中展示的是一個物件,這是react特有的物件,然後type對應h1,props對應內部文字節點
let objMale = {
type:`div`,
props:{
children:[`hello`]
}
};
//大致是這樣的一個結構,這已經成為我們可以看懂的js物件了吧。
然後開始分析程式碼,ReactDom.render(objMale,document.getElementById(`root`)),這一層render做了什麼事情
客觀分析,定義了一個JSX Dom元素,<div>hello</div>,render只是將他給插入到頁面中
簡單定義一個函式 _render 名字隨便起
function _render(jsxDom,container){
//首先通過解構賦值 然後建立一個元素節點吧。
let {type,props} = jsxDom;
let newEle = document.createElement(type);//注意手法,這裡就是將jsxDom,通過type為div 的轉換成一個Dom元素
<!--
下一步操作 _nextRender (主要目的就是將props中的內容給新增到新建立的Dom元素中)
-->
//最終輸出的就是講建立的DOM元素插入到容器 -->
container.appendChild(newEle)
}
_render(objMale,document.getElementById(`root`));
//大體來說無非就是這種操作,下一步也就是把渲染的元素加上相應的文字節點,
//可以列印一下 React.createElement(`div`,{id:1,className:`girl`},[`hello`]) 這個物件看一下props
function _nextRender(newEle,props){
//props不僅僅可能是一個物件
for ( let attr in props){
//介於react中的一些關鍵字不能和js中衝突,,jsx className <=> class class jsxom htmlFor <=> js for
//這裡需要加一些判斷
if(attr == `children`){
//這裡對應上面擴充套件的巢狀邏輯 我的children裡面也可能是個物件吧。這時候就要用到遞迴(知識點哦)
props.forEach((item)=>{
//這裡只有倆種可能,一種是字串,一種是子元素(子元素依然會和父元素的jsxDom保持一致)
if(typeof item == `string`){ //判斷為字串 直接新增
newEle.appendChild(item)
}else{ //否則就是元素 遞迴,,_render(當前子元素物件,上一級建立的容器)
_render(item,newEle);
}
})
}else if (attr == `className`){
newEle.setAttribute(`class`,props[attr])
}else if(attr == `className`){
newEle.setAttribute(`for`,props[attr])
}else{
newEle.setAttribute(attrr`,props[attr])
}
}
}
let mulObj = {
type:`div`,
props:{
className:`ai`,
id:1,
children:[`hello`,{
type:`span`,
props:{
className:`xi`,
id:2,
children:[`juejin`]
}
}]
}
};
let jsxObj = <div className="ai" id="1">hello<span className="xi" id="2">juejin</span></div>
最終渲染在頁面上就都是 <div class="ai" id="1">hello<span class="xi" id="2">juejin</span></div>
_render(mulObj,document.getElementById(`root`)); === ReactDom.render(jsxObj,document.getElementById(`root`))
並不是完全相等,只是在渲染邏輯上差不多。
複製程式碼