wordpress修改域名后打不開搜索引擎優(yōu)化方法有哪些
文章目錄
- jsx的介紹與語法
- 1.真實DOM和虛擬DOM
- 2.jsx語法
- 模塊與模塊化,組件與組件化
- 模塊與模塊化
- 組件與組件化
- React組件
- React事件綁定
- 函數(shù)式組件
- 類式組件
- 組件屬性state
- 組件屬性props
- 組件屬性ref
尚硅谷react教程+官方文檔學習記錄筆記01
jsx的介紹與語法
1.真實DOM和虛擬DOM
虛擬DOM本質(zhì)是一般對象(Object對象),虛擬DOM的附帶屬性比真實DOM少,更輕量,虛擬DOM最終會被React轉(zhuǎn)換成真實DOM顯示在頁面上。
<body><div id="h1">真實DOM</div><!-- ....省略引入react有關js文件,示范虛擬DOM渲染過程--><script type="text/babel">const vdom = <h1> Hello JS <h1/>; // 虛擬DOMReactDOM.render(vdom,document.getElementById('h1')); // 將虛擬DOM渲染到頁面</script>
</body>
2.jsx語法
jsx語法是react定義的js+XML的語法,本質(zhì)是React.creatElement(component,props,…children)的語法糖,用來簡化和創(chuàng)建虛擬DOM。
// babel轉(zhuǎn)譯jsx成React.createElement()函數(shù)調(diào)用
const element = (<h1 className="greeting">Hello, world!</h1>
);
const element = React.createElement('h1',{className: 'greeting'},'Hello, world!'
); // 兩段代碼等效
語法規(guī)則一:定義虛擬DOM變量,賦值不寫引號
// 例子 創(chuàng)建一個h1標簽的虛擬DOM
var element = <h1> Hello JS </h1> // 最終產(chǎn)生一個JS對象// 創(chuàng)建嵌套標簽
var element = (<h1><span> Hello JS </span></h1>) // ()表示這一段為一個整體
語法規(guī)則二:標簽中需要混入js表達式時使用{},表達式為可以接在=后的(let x = 表達式)
const data = "Hello JS";
var element = (<h1><span> {data} </span> <span> {data.toLowerCase()} </span> </h1>)
// 使用jsx動態(tài)顯示列表,頁面顯示一個列表,有a,b,c三個項,每個li標簽必須有唯一的key值,這里為數(shù)組的下標
const data = [ 'a','b','c'];
const element = (<div><ul>{data.map((item,index)=>{return <li key ={index}< {item} </li>})} // 這里的花括號里面是一個表達式</ul></div>
)
語法規(guī)則三:樣式的類名使用className,內(nèi)聯(lián)樣式使用style={{key:value}}。
var element1 = <h1 className="title"> Hello JS </h1>
var element2 = <h1 style={{color:'white', fontSize:'20px'}}> Hello JS </h1> // 類似font-size由多個詞連接的屬性改為小駝峰寫法
語法規(guī)則四:虛擬DOM只能有一個根標簽
var h1 = (<h1><span> {data} </span> <span> {data.toLowerCase()} </span> </h1>) // h1為根標簽var span = (<span> {data} </span> <span> {data.toLowerCase()} </span> ) // 錯誤,有兩個根標簽span
語法規(guī)則五:標簽必須閉合,單標簽以“/”結(jié)尾或者使用閉合標簽
<input />
<input ></input>
語法規(guī)則六:標簽的首字母規(guī)范:
1)以小寫字母開頭,則轉(zhuǎn)換為html同名標簽,若html無對應標簽,報錯;
2)以大寫字母開頭,react渲染該組件,若組件未定義,報錯;
語法規(guī)則七:使用{/* 內(nèi)容 */}在jsx內(nèi)寫注釋。應避免在jsx結(jié)構內(nèi)寫注釋
var element = (<div> {/* <h1>這是注釋掉的標簽</h1> */}<h1>這是未注釋標簽</h1></div> )
模塊與模塊化,組件與組件化
模塊與模塊化
模塊:提供特定js功能的程序,一般指一個js文件;將代碼拆成模塊可以簡化js,提高js運行效率;
模塊化:應用的js都以模塊編寫
組件與組件化
組件:實現(xiàn)局部功能效果代碼的資源集合,包含html,css,js,image,video等,考慮復用性,簡化項目編碼,提高運行效率;
組件化:應用以多組件的方式實現(xiàn)
React組件
在Chorme里導入ReactDevTool插件;
React事件綁定
react把js原生事件onXXX方法重寫了,變成小駝峰寫法,比如onclick方法變?yōu)閛nClick方法,使用時需要注意。函數(shù)調(diào)用時使用{}包含函數(shù)名。
<button onclick="activateLasers()"></button> // 原生寫法
<button onClick={activateLasers}></button> // react寫法
函數(shù)式組件
定義一個函數(shù),函數(shù)名首字母大寫,返回虛擬DOM,調(diào)用react的render方法時,使用閉合標簽<函數(shù)名/>作為第一個參數(shù)
// 函數(shù)組件
<body><div id="test"></div><!--引入react有關js文件--><script type="text/javascript" src="react.development.js"></script><script type="text/javascript" src="react-dom.development.js"></script><script type="text/javascript" src="babel.min.js"></script><script type="text/babel">// 創(chuàng)建函數(shù)式組件function Demo(){return <h1> Hello JS <h1/>;}// 渲染頁面。過程:React解析組件標簽,尋找Demo組件,發(fā)現(xiàn)組件是函數(shù)Demo定義的,調(diào)用Demo函數(shù),返回虛擬DOMReactDOM.render(<Demo/>,document.getElementById('test')); </script>
</body>
類式組件
定義一個類,繼承React.Component類,無變量需要傳遞獲取,不寫supper方法,必須寫render方法,返回虛擬DOM
// 類組件
<body><div id="test"></div><!--....省略引入react有關js文件--><script type="text/babel">
// 創(chuàng)建類式組件
class Welcome extends React.Component {render() {return <h1>Hello</h1>;}
}// 渲染頁面。過程:React解析組件標簽,尋找Welcome組件,發(fā)現(xiàn)組件是類Welcome定義的,然后new一個Welcome實例對象,通過Welcome實例對象調(diào)用Welcome類里的render方法,返回虛擬DOMReactDOM.render(<Welcome/>,document.getElementById('test')); </script>
</body>
簡單組件(h函數(shù)組件)與復雜組件(類組件)區(qū)別在于有無狀態(tài)State
組件屬性state
狀態(tài)(state)驅(qū)動頁面。
類組件對象實例自帶state屬性,值為null。當需要使用state取值時,借助構造器初始化state為對象,將需要的變量掛在state對象上。
// 初始化并獲取state
<body><div id="test"></div><!--....省略引入react有關js文件--><script type="text/babel">
class Weather extends React.Component {// 定義構造器constructor(props){super(props);this.state = {isHot:false} // 借助構造器初始化state}render() {return <h1>天氣{this.state.isHot ? '熱' : '涼'}</h1>; // 獲取state}
}ReactDOM.render(<Weather/>,document.getElementById('test')); </script>
</body>
// 實現(xiàn)點擊事件
class Weather extends React.Component {constructor(props){super(props);this.state = {isHot:false};this.changeWeather = this.changeWeather.bind(this); // 3. bind方法返回一個新函數(shù),綁定在參數(shù)this上;這里bind(this)綁定了類的實例對象,這一行右邊表示將類的changeWeather方法綁定在實例對象上,左邊將綁定的函數(shù)取名為changeWeather}render() {return <h1 onClick={this.changeWeather}>天氣{this.state.isHot ? '熱' : '涼'}</h1>; // 2.添加點擊事件,這里相當于把類方法changeWeather作為onClick的回調(diào),所以當用戶點擊時,this不是實例對象,且嚴格模式不能指向window,所以為undefined}// 點擊事件changeWeather(){console.log(this); // 1.類中的方法默認開啟局部嚴格模式,非對象實例調(diào)用時,this指向undefined}
}
// 實現(xiàn)點擊事件,理解以上注釋部分
class Weather extends React.Component {constructor(props){super(props);this.state = {isHot:false};this.change = this.changeWeather.bind(this); }render() {return <h1 onClick={this.change}>天氣{this.state.isHot ? '熱' : '涼'}</h1>; }// 點擊事件changeWeather(){console.log(this); }
}
state不能直接更改,更新要借助api setState()方法。
// 點擊事件里更改state里的變量 -- 直接更改changeWeather(){const isHot = this.state.isHot; // 獲取原來的isHot值this.state.isHot = !isHot; // 點擊后,借助開發(fā)插件可以看到this.state.isHot值沒有變化,頁面也無變化,react不允許直接改變狀態(tài)}// 點擊事件里更改state里的變量 -- 借助setState()方法changeWeather(){const i = this.state.isHot; // 獲取原來的isHot值this.setState({isHot:!i}); // 點擊后,借助開發(fā)插件可以看到this.state.isHot值發(fā)生變化,頁面也隨state改變而改變}
setState方法起到的是一個合并的動作。
// 原state
state = {a:1,b:2,c:0}
// 使用setState()更新
this.setState({a:99});
// 更新后的state為
state = {a:99,b:2,c:0}
精簡state寫法,避免有多屬性和多方法需要綁定。在類組件的類里使用屬性名+賦值語句+值/函數(shù)。賦值的函數(shù)定義必須使用箭頭函數(shù)。
class Weather extends React.Component {state = {isHot:false} // 往實例對象上掛一個state屬性,值為一個對象,里面有isHot屬性render() {return <h1 onClick={this.changeWeather}>天氣{this.state.isHot ? '熱' : '涼'}</h1>; }changeWeather = ()=>{const i = this.state.isHot; this.setState({isHot:!i}); } // 往實例對象上掛一個changeWeather屬性,值為一個方法,方法里更新state。為什么使用箭頭函數(shù)不使用function定義?因為箭頭函數(shù)沒有自己的this,箭頭函數(shù)的this指向上下文的this,也就是實例對象
}
總結(jié)
1.state是對象,包含一個或多個key-value的組合,不能直接修改更新。
2.通過setState()方法更新state,從而從新渲染頁面。
3.render()方法中的this指向的也是類組件的實例對象。
4.組件自定義方法的this為undefined時,在構造器里使用bind方法或使用賦值語句箭頭函數(shù)改變this。
5.適用于用戶數(shù)據(jù)交互渲染頁面。
組件屬性props
類組件對象實例自帶props屬性,值為{}。在ReactDOM.render方法內(nèi)使用key="value"的方式傳參,jsx內(nèi)使用this.props.屬性的方式接收。
// props的基本使用
class Person extends React.Component{ render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}
ReactDOM.render(<Person name="tom" age="18" sex="男"/>,document.getElementById('test')); // 這里傳遞的age為字符串
ReactDOM.render(<Person name="tom" age={18} sex="男"/>,document.getElementById('test')); // 這里傳遞的age為Number
傳遞多個props屬性時,使用{}+擴展運算符“…”
// 傳遞多個props屬性
class Person extends React.Component{ render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}// 定義變量,包含需要的屬性
const p = {name:"tom",age:"18",sex:"男"};
// 傳遞時使用{}
ReactDOM.render(<Person {...p}/>,document.getElementById('test'));
對props屬性做限制,如參數(shù)類型,默認值,必要性
// 寫法1--在類的外部
// 對類組件定義一個propTypes屬性,屬性內(nèi)規(guī)定了props各個屬性的類型
類名.propTypes = {屬性1: PropTypes.string.isRequired, // 使用isRequired標定為必要字段屬性2: PropTypes.number
}
// 對類組件定義一個defaultProps屬性,屬性內(nèi)規(guī)定了props內(nèi)各個屬性的默認值
類名.defaultProps = {屬性1:'默認值',屬性2:'默認值'
}// 寫法2--在類的內(nèi)部
class 類名{static propTypes = {屬性1: PropTypes.string.isRequired, 屬性2: PropTypes.number}static defaultProps = {屬性1:'默認值',屬性2:'默認值'}// ...state,render等
}
// ... 增加一個引入文件,以使用對標簽屬性增加限制的方法
<script type="text/javascript" src="prop-types.js"></script>
<script type="text/babel">
class Person extends React.Component{ render(){return (<ul><li>name:{this.props.name}</li><li>sex:{this.props.sex}</li><li>age{this.props.age}</li></ul>)}}
// 對標簽屬性進行類型和必要性限制
Person.propTypes = {name: PropTypes.string.isRequired,age:PropTypes.number
}
// 對標簽屬性指定默認值
Person.defaultProps = {sex:'未知'
}
const p = {name:"tom",age:"18",sex:"男"};
ReactDOM.render(<Person {...p}/>,document.getElementById('test'));
</script>
對類組件傳遞方法
// 寫法--在類的外部
Person.propTypes = {speak: PropTypes.func
}
function speak(){console.log('say something')
}
ReactDOM.render(<Person speak={speak}/>,document.getElementById('test'))
函數(shù)式組件使用props,組件三大屬性中值由props可以在函數(shù)式組件使用。
function Person(props){return (<ul><li>name:{props.name}</li><li>sex:{props.sex}</li><li>age{props.age}</li></ul>)
}
Person.propTypes = {name: PropTypes.string.isRequired,age:PropTypes.number
}
Person.defaultProps = {sex:'未知'
}
ReactDOM.render(<Person name="tom" age={18} sex="男"/>,document.getElementById('test'))
總結(jié)
1.props屬性只讀,使用this.props.屬性=值會報錯。
2.組件標簽的所有屬性都保存在props中,通過標簽屬性從組件外向組件內(nèi)傳遞變化的數(shù)據(jù),組件內(nèi)不要修改props數(shù)據(jù)。
3.適用于父傳子,組件間通信。
組件屬性ref
類組件對象實例自帶refs屬性,值為{}。類似原生html標簽的id屬性。
<標簽 ref="屬性名"></標簽> // 在標簽內(nèi)定義
this.refs.屬性名 // 使用
// refs基本使用
class Demo extends react.Component{showData = ()=>{console.log(this.refs); // {input1:input,button1:button,input2:input} input1是input標簽的ref值,冒號后的input表示的是ref為input1的這一個input標簽節(jié)點console.log(this.refs.input1); // <input type="text" placeholder=""/>}render(){return (<div><input ref="input1" type="text" placeholder="點擊按鈕"/><button ref="button1" onClick="{this.showData}">點擊提示左側(cè)數(shù)據(jù)</button><input ref="input2" type="text" placeholder=""/></div>)}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));
以上為refs的字符串寫法,ref屬性都為字符串類型,會有效率問題。因此有了回調(diào)函數(shù)形式的ref。
<標簽 ref={箭頭函數(shù)}></標簽> // 在標簽內(nèi)定義,在創(chuàng)建節(jié)點時自動調(diào)用箭頭函數(shù)
<標簽 ref={(a)=>{this.屬性名=a}}></標簽> // 在標簽內(nèi)定義,指定ref屬性名
this.屬性名 // 使用,因為直接掛在了實例對象上,所以可以直接使用this
// refs回調(diào)函數(shù)形式,使用內(nèi)聯(lián)函數(shù)
class Demo extends react.Component{showData = ()=>{console.log(this.input2.value)}render(){return (<div><input ref={(a)=>{console.log(a)}} type="text" placeholder="點擊按鈕"/> // 打印<input type="text" placeholder="點擊按鈕"/><input ref={(a)=>{this.input2=a}} type="text" placeholder=""/> // 獲取當前所在的節(jié)點(a,也就是input標簽),將這個節(jié)點掛在組件實例對象上,并命名為input2<button ref="button1" onClick="{this.showData}">點擊提示左側(cè)數(shù)據(jù)</button></div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));
以上是使用內(nèi)聯(lián)函數(shù)的形式定義ref回調(diào)函數(shù),內(nèi)聯(lián)函數(shù)在組件更新的時候會被執(zhí)行兩次,第一次傳入?yún)?shù)null,第二次才傳入DOM元素。因為每次調(diào)用render方法進行渲染時,都會創(chuàng)建一個新的函數(shù)實例,React會清空舊的ref然后設置一個新的,當舊的被清空,無法找到當前節(jié)點,所以第一次傳入null。
// refs回調(diào)函數(shù)形式,使用內(nèi)聯(lián)函數(shù),組件更新二次執(zhí)行回調(diào)函數(shù)問題
class Demo extends react.Component{state = {isHot:'hot'}showData = ()=>{alert(this.input2.value)}showWeather = ()->{const isHot = this.state.isHot;this.setState({isHot:!isHot});}render(){return (<div><input ref={(a)=>{this.input2=a;console.log(a)}} type="text" placeholder=""/> <button ref="button1" onClick="{this.showData}">點擊提示左側(cè)數(shù)據(jù)</button>// 點擊提示數(shù)據(jù)按鈕,內(nèi)聯(lián)函數(shù)調(diào)用一次,打印<input type="text" placeholder=""/><button onClick="{this.showWeather}">點擊提示天氣</button>// 點擊顯示天氣按鈕,內(nèi)聯(lián)函數(shù)調(diào)用兩次,第一次打印null第二次打印<input type="text" placeholder=""/></div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));
下面類綁定式的ref寫法可以避免調(diào)用兩次的情況,但使用內(nèi)聯(lián)函數(shù)調(diào)用兩次的影響無關緊要,可繼續(xù)使用。
函數(shù)名=(a)=>{this.屬性名=a} // 在類組件內(nèi)定義函數(shù)
<標簽 ref=this.函數(shù)名></標簽> // 在標簽內(nèi)定義
// refs回調(diào)函數(shù)形式,使用類綁定的形式,解決組件更新時二次執(zhí)行回調(diào)函數(shù)問題
class Demo extends react.Component{state = {isHot:'hot'}showData = ()=>{alert(this.input2.value)}showWeather = ()->{const isHot = this.state.isHot;this.setState({isHot:!isHot});}showInput = (a)=>{this.input2=a;console.log(a)}render(){return (<div><input ref={this.showInput} type="text" placeholder=""/> <button ref="button1" onClick="{this.showData}">點擊提示左側(cè)數(shù)據(jù)</button>// 點擊提示數(shù)據(jù)按鈕,內(nèi)聯(lián)函數(shù)調(diào)用一次,打印<input type="text" placeholder=""/><button onClick="{this.showWeather}">點擊提示天氣</button>// 點擊顯示天氣按鈕,內(nèi)聯(lián)函數(shù)不會被頻繁調(diào)用</div> )}
}
ReactDOM.render(<Demo/>,document.getElementById('test'));
React.createRef調(diào)用后返回一個容器,容器內(nèi)存儲被ref標識的一個節(jié)點,每個被ref標識的節(jié)點都有專屬自己的容器。
// 在類組件內(nèi),掛在類組件的實例對象上
myRef = React.createRef();
// 在虛擬DOM中
<input ref={this.myRef} type="text" />
// React.createRef的基本使用
class Demo extends React.Component{myRef = React.createRef()myRef2 = React.createRef()showRef(){console.log(this.myRef); // {current:input}console.log(this.myRef.current); //<input type="text" />console.log(this.myRef.current.value); // 輸入框輸入的值}render(){return (<div><input ref={this.myRef} type="text" /><input ref={this.myRef2} type="text" /><button onClick={this.showRef}>點擊</button></div>)}
}