1. 程式人生 > 實用技巧 >7.Redis詳解(七)------ AOF 持久化

7.Redis詳解(七)------ AOF 持久化

技術標籤:reactreact

JSX

const element=<h1>hello,world</h1>;

JSX是javascript的語法拓展,JSX產生react元素。

react是使用包含標記和邏輯共同放到元件中來實現分離關注點。react不強制使用JSX,但是JSX作為輔助和UI一起很有用,它能讓React顯示更多有用的錯誤和警告訊息。

在JSX中嵌入表示式

const name='zyy';

const element=<h1>hello,{name}</h1>;【{}內可以是2+2,user.name,fn(user)】

ReactDom.render(

element,

document.getElementById('root');

);

呼叫JavaScript函式的結果嵌入fn(user)<h1>元素中

function fn(user){

return user.firstName+' '+user.lastName;

}

const user={

firstName:'zhu',

lastName:'Yuanyuan'

}

const element=(

<h1>

hello,{fn(user)}!

</h1>

);

ReactDom.render{

element,

document.getElementById('root')

};

在編譯之後,JSX 表示式會被轉為普通 JavaScript 函式呼叫,並且對其取值後得到 JavaScript 物件。,即在if語句和for迴圈內部可以使用JSX

使用JSX指定屬性

可以通過使用引號,來將屬性值指定為字串字面量:

const element=<div tabIndex="0"></div>

也可以使用大括號,在屬性值中插入一個 JavaScript 表示式:

const element=<img src={user.url}></img>

使用 JSX 指定子元素

假如一個標籤裡面沒有內容,你可以使用/>

來閉合標籤

const element = <img src={user.avatarUrl} />;

JSX 標籤裡能夠包含很多子元素:

const element = (
  <div>
    <h1>Hello!</h1>
    <h2>Good to see you here.</h2>
  </div>
);

JSX防止XSS攻擊

React DOM 在渲染所有輸入內容之前,預設會進行轉義。它可以確保在你的應用中,永遠不會注入那些並非自己明確編寫的內容。所有的內容在渲染之前都被轉換成了字串,因此惡意程式碼無法成功注入,從而有效地防止了 XSS 攻擊。

JSX表示物件

Babel將JSX編譯為React.createElement()呼叫。

const element = (
  <h1 className="greeting">
    Hello, world!
  </h1>
);
const element = React.createElement(
  'h1',
  {className: 'greeting'},
  'Hello, world!'
);

從本質上講,React.creatElement()會建立一個像這樣的物件:

// Note: this structure is simplified
const element = {
  type: 'h1',
  props: {
    className: 'greeting',
    children: 'Hello, world!'
  }
};

這些物件叫“React元素”,它們描述了你希望在螢幕上看到的內容。React讀取這些物件然後使用它們來構建 DOM 以及保持隨時更新

元素渲染

元素是構成 React 應用的最小磚塊,React DOM 會負責更新 DOM 來與 React 元素保持一致。

想要將一個 React 元素渲染到根 DOM 節點中,只需把它們一起傳入ReactDOM.render()

react元素是不可變物件,建立元素後,就無法更改它的子元素或屬性。一個元素代表了某一時刻的UI。

時鐘案例:

function tick(){

const element=(

<div>

<h1>hello,world</h1>

<h2>{new Date().toLocaleTimeString()}</h2>

</div>

);

ReactDom.render(element,document.getElementById('root'));

}

setIntervel(tick,1000);

React 只更新它需要更新的部分

元件和props

元件允許你分隔UI為獨立的、可重用的零件,每個零件是隔離的。
概念上,元件就像js的函式。它們接收任意的輸入(被稱為 'props'),並返回React元素,用以描述應該在螢幕上顯示的內容。

函式元件和class元件

函式元件

function Welcome(props){

return <h1>hello,{props.name}</h1>;【它接收單個的 'props' 物件引數,並返回一個 'React元素'】

}

class元件

class Welcome extends React.component{

render(){

return <h1>hello,{this.props.name}</h1>;

}

}

element也能代表使用者定義的元件:

當 React 元素為使用者自定義元件時,它會將 JSX 所接收的屬性(attributes)以及子元件(children)轉換為單個物件傳遞給元件,這個物件被稱之為 “props”。

function Welcome(props){

return <h1>hello,{props.name}</h1>;

}

const element=<Welcome name="zyy"/>;

ReactDom.render(

element,

document.getElementById('root')

);

注:元件名首字母大寫。

組合元件

元件可以在其輸出中引用其他元件。這就可以讓我們用同一組件來抽象出任意層次的細節。

例子:建立一個app元件,多次渲染welcome元件

function Welcome(props){
return <h1>hello,{props.name}</h1>;

}

function App(){

return( <div>

<Welcome name="zhu" />

<Welcome name="Yuan" />

<Welcome name="yuan" />

</div>

);

}

ReactDom.render(

<App />,

document.getElementById('root')

);

props是隻讀的

props會傳遞給元件,所以不能修改props

state和生命週期

state類似props,但是它是私有的,並且完全由元件控制。

將函式轉換為類

  1. 建立一個具有相同名稱的,可擴充套件的ES6類React.Component
  2. 向其中新增一個名為的空方法render()
  3. 將函式的主體移到render()方法中。
  4. 更換propsthis.propsrender()身體。
  5. 刪除剩餘的空函式宣告。

Clock extends React.Component{

render(){

return (

<div>

<h1>hello,world</h1>

<h2>It is {this.props.date.toLocalETimeString()}</h2>

</div>

);

}

}

function tick(){

ReactDom.render(

<Clock date={new Date()} />,

document.getElementById('root')

);

}

setInterval(tick,1000);

向類中新增區域性state

通過3步,將props中的data移動到state。

  1. 在方法中替換this.props.date為:this.state.date
  2. 新增一個分配初始值的類建構函式this.state
  3. date<Clock />元素中刪除道具:

Clock extends React.Component{

constructor(props){

super(props);

this.state={date: new Date()};

}

render(){

return (

<div>

<h1>hello,world</h1>

<h2>It is {this.state.date.toLocalETimeString()}</h2>

</div>

);

}

}

ReactDom.render(

<Clock />,

document.getElementById('root')

);

將生命週期方法新增到類中

clock元件首次渲染為dom時,我們設定了一個計時器(set up a timer)。這在React中,被稱作 'mounting'
當移除由clock元件產生的dom時,我們清除mount設定的計時器。這在React中,被稱作 'unmouting'

我們可以在元件類中,宣告一些特殊的方法,當元件 mount 和 unmount 時,來執行我們設定的程式碼:

Clock extends React.Component{

constructor(props){

super(props);

this.state={date: new Date()};

}

componentDidMount(){

}

componentWillUnmount(){

}

render(){

return (

<div>

<h1>hello,world</h1>

<h2>It is {this.state.date.toLocalETimeString()}</h2>

</div>

);

}

}

元件輸出已經被渲染為dom後,執行 'componentDidMount()' 鉤子。這是個設定計時器的好地方:

componentDidMount(){

this.timerId=setInterval(

()=>this.tick(),1000

);

}

this.props由React自身建立,而this.state有特殊的意義,如果你需要儲存一些資料,且這些資料並不用於可見輸出(the visual output),你可以手動給元件類新增額外的欄位
如果你在 render() 中不使用其他欄位,則不應該在 state 中新增這些欄位

在 'componentWillUnmount' 生命週期鉤子中,清除計時器:

componentWillUnmount(){
clearInterval(this.timerId);

}

實現tick():

tick() {    
   this.setState({      
      date: new Date()    
    });  
}

整個程式碼:

Clock extends React.Component{

constructor(props){

super(props);

this.state={date: new Date()};

}

componentDidMount(){

this.timerId=setInterval(

()=>this.tick(),1000

);

}

componentWillUnmount(){
clearInterval(this.timerId);

}

tick() {
this.setState({
date: new Date()
});
}

render(){

return (

<div>

<h1>hello,world</h1>

<h2>It is {this.state.date.toLocalETimeString()}</h2>

</div>

);

}

}

ReactDom.render(

<Clock />,

document.getElementById('root')

);

正確使用state

1.不要直接修改狀態,而是使用setState()。建構函式是唯一可以給this.state賦值的地方:

// Wrong
this.state.comment = 'Hello';
// Correct
this.setState({comment: 'Hello'});

2.state的更新可能是非同步的。

出於效能考慮,React 可能會把多個setState()呼叫合併成一個呼叫。

因為this.propsthis.state可能會非同步更新,所以你不要依賴他們的值來更新下一個狀態。

為了解決這個問題,可以讓setState()接收一個函式而不是一個物件。

這個函式用上一個 state 作為第一個引數,將此次更新被應用時的 props 做為第二個引數:

// Correct
this.setState((state, props) => ({
  counter: state.counter + props.increment
}));

3.state的更新會被合併

當你呼叫setState()的時候,React 會把你提供的物件合併到當前的 state。

4.state 為區域性的原因:只有擁有並設定state的元件能訪問到state,其他元件都無法訪問。

5.元件可以選擇把它的 state 作為 props 向下傳遞到它的子元件中:

<FormattedDate date={this.state.date} />

“自上而下”或是“單向”的資料流。任何的 state 總是所屬於特定的元件,而且從該 state 派生的任何資料或 UI 只能影響樹中“低於”它們的元件

事件處理

React 元素的事件處理和 DOM 元素的很相似,但

  • react事件的命名採用駝峰命名式,
  • 使用 JSX 語法時需要傳入一個函式作為事件處理函式,而不是一個字串。

HTML:

<button onclick="activateLasers()">
  Activate Lasers
</button>

React:

<button onClick={activateLasers}>  
   Activate Lasers
</button>
  • 不能通過返回false的方式阻止預設行為,必須顯式的使用preventDefault()

比如阻止連結預設開啟一個新頁面

HTML

<a href="#" onclick="console.log('The link was clicked.'); return false">
  Click me
</a>

React:

function ActionLink() {
  function handleClick(e) {    
      e.preventDefault();    
      console.log('The link was clicked.');  
   }
  return (
    <a href="#" onClick={handleClick}>      
      Click me
    </a>
  );
}

使用ES6 類 定義一個元件時,通常的做法是將事件處理函式宣告為 class 中的方法。

例如:Toggle元件,渲染一個讓使用者切換開關狀態的按鈕。

class Toggle extends React.component{

constructor(props){

super(props);

this.state={ isToggleOn: true };

this.handleClick=this.handleClick.bind(this);

}

handleClick(){

this.setState((state)=>{

isToggleOn:!state.isToggleOn

});

}

render(){

return (

<button onClick={this.handleClick}>

{this.state.isToggleOn?'On':'Off'}

</button>

);

}

}

ReactDom.render(

<Toggle />,

document.getElementById('root')

);

【通常情況下,如果你沒有在方法後面新增(),你應該為這個方法繫結this。或用箭頭函式,但是不推薦使用,因為每次渲染元件都會建立不同的回撥函式,而且如果該回調函式作為props傳入子元件,這些元件可能進行額外的重新渲染】

向事件處理函式傳遞引數

1.箭頭函式

2.Function.prototype.bind()

<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>

條件渲染

在 React 中,可以建立不同的元件來封裝各種需要的行為。依據應用的不同狀態,可以只渲染對應狀態下的部分內容。