摘要:中的方法調(diào)用了并傳入了最新的值。在前一次渲染中,已經(jīng)將的設(shè)置為,并將的設(shè)置為
本文采用 es6 語法,完全參考 https://reactjs.org/docs/安裝
本文完全參考 React 官方 Quick Start 部分,除了最后的 thinking-in-react 小節(jié)
首先你需要點(diǎn)擊安裝 nodejs(npm)。然后執(zhí)行:
npm install -g create-react-app
如果上述命令執(zhí)行失敗可以運(yùn)行以下命令:
npm install -g create-react-app --registry=https://registry.npm.taobao.org
然后建立一個(gè) react 并運(yùn)行:
create-react-app myApp cd myApp npm start
這樣你就簡(jiǎn)單的完成了一個(gè) react app 建立,其目錄結(jié)構(gòu)如下( 圖中不包括 node_modules 目錄,下同 ):
Hello World我們刪除一些不必要的東西,然后修改目錄結(jié)構(gòu)如下(不能刪 node_modules 目錄,如果刪了就在項(xiàng)目目錄下運(yùn)行 npm i 就好了):
其中 components 是個(gè)目錄。
修改 index.js 如下:
import React from "react"; import ReactDOM from "react-dom"; ReactDOM.render(hello world!
, document.getElementById("root") );
然后命令行運(yùn)行:
npm start
你就可以看到熟悉的 "hello world" 了
JSXJSX 是 react 中允許 js 和 html 混寫的語法格式,需要依賴 babel 編譯。這里我就只研究它的語法:
const element =Hello, world!
;
可以通過花括號(hào)在其中插入表達(dá)式:
function formatName(user){ return user.firstName + " " + user.lastName; } const user = { firstName: "Harper", lastName: "Perez" }; const element = (Hello, {formatName(user)}!
); ReactDOM.render( element, document.getElementById("root") );
可以將 HTML 語句寫為多行以增加可讀性,用小括號(hào)括起來可以防止自動(dòng)插入分號(hào)導(dǎo)致的錯(cuò)誤。
JSX 也是個(gè)表達(dá)式,所以可以用在 for 和 if 中:
function getGreeting(user){ if (user){ returnHello, {formatName(user)}!
; } returnHello, Stranger.
; }
我們可以正常使用引號(hào)給 HTML 標(biāo)簽添加屬性,也可以使用 js 表達(dá)式
const element = ; const element = ; //注意空標(biāo)簽以 /> 結(jié)尾,像 XML 一樣
注意 html 屬性名請(qǐng)使用小駝峰(camelCase)寫法
React 會(huì)在渲染之前 escape 所有在 JSX 嵌入的值,可以有效的防止 XSS 攻擊。
babel 會(huì)編譯 JSX 成 React.createElement() 的參數(shù)調(diào)用:
const element = (Hello, world!
); // 編譯為以下形式 const element = React.createElement( "h1", {className: "greeting"}, "Hello, world!" );
而 React.createElement() 會(huì)生成這樣一個(gè)對(duì)象(React 元素):
const element = { type: "h1", props: { className: "greeting", children: "Hello, world" } };元素渲染
在 ./public/index.html 中有一個(gè) id 為 root 的 div。我們將這個(gè) div 作為 react 渲染的容器。
回看 hello world 程序,通過 ReactDOM.render() 方法很輕松的把內(nèi)容渲染到了目標(biāo)容器上:
ReactDOM.render(hello world!
, document.getElementById("root") );
當(dāng)然也可以這樣寫:
let content =hello world!
; ReactDOM.render( content, document.getElementById("root") );
下面我們寫一個(gè)復(fù)雜的,這是個(gè)實(shí)時(shí)更新的時(shí)鐘,通過 setInerval 每隔 1s 調(diào)用 ReactDOM.render:
function Tick(){ const element = (); ReactDOM.render( element, document.getElementById("root") ); } setInterval(Tick, 1000);Hello, world!
It is {new Date().toLocaleTimeString()}.
重寫上面時(shí)鐘組件的代碼如下,使其組件化程度更高:
function Clock(props){ return (組件); } function Tick(){ ReactDOM.render( //這個(gè)地方不得不傳入一個(gè)參數(shù), 但理論上獲取一個(gè)時(shí)鐘直接獲取就可以了,這個(gè)問題我們后面再解決Hello, world!
It is {props.date.toLocaleTimeString()}.
, document.getElementById("root") ); } setInterval(Tick, 1000);
React 給我們提供了更好的管理我的代碼——組件。這里我們還是首先我們先了解一下自定義標(biāo)簽:
const element =;
對(duì)這個(gè)標(biāo)簽的理解也不難,它實(shí)際上調(diào)用了 Welcome 函數(shù),并且將所有的屬性(這里只有name)打包為一個(gè)對(duì)象傳給 Welcome 函數(shù)。所以下面這個(gè)代碼輸出 ”Hello Sara"
function Welcome(props){ returnHello, {props.name}
; } const element =; ReactDOM.render( element, document.getElementById("root") );
組件幫助我事先一些重復(fù)的工作,比如這樣:
function Welcome(props){ returnHello, {props.name}
; } function App(){ return (); } ReactDOM.render(, document.getElementById("root") );
我們可以通過傳遞參數(shù)得到同一個(gè)組件構(gòu)建的不同模塊。
這里我們需要補(bǔ)充一個(gè)重要的概念:__純函數(shù)!!!__
如果一個(gè)函數(shù)執(zhí)行過程中不改變其參數(shù),也不改變其外部作用于參數(shù),當(dāng)相同的輸入總能得到相同的值時(shí),我們稱之這樣的函數(shù)為純函數(shù)。__React 要求所有組件函數(shù)都必須是純函數(shù)。__
其實(shí)之前的一段代碼中 Tick, Welcome 函數(shù)就可以看做是一個(gè)組件,同時(shí) React 建議組件名的首字母大寫。但是更多情況下我們會(huì)用到 es6 的語法構(gòu)建組件。以之前時(shí)鐘代碼為例,轉(zhuǎn)換過程分為五個(gè)步:
新建一個(gè)類,類名同組件函數(shù)名Clock,并繼承自 React.Component;
給該類添加一個(gè)方法 render(/無參數(shù)/);
將 Clock 的函數(shù)體作為該函數(shù)的函數(shù)體;
將 render 方法中的 props 換為 this.props;
刪除原有的 Clock 函數(shù)
結(jié)果如下:
class Clock extends React.Component { render(){ return (); } }Hello, world!
It is {this.props.date.toLocaleTimeString()}.
但這樣計(jì)時(shí)的功能就不能用了,我們繼續(xù)往下看……
State 和 Lifecycle解決上面這個(gè)問題,就需要用到 State 和 Lifecycle 的知識(shí)了
我們給 Clock 類添加一個(gè)構(gòu)造函數(shù),并且刪除 Clock 標(biāo)簽中的參數(shù):
class Clock extends React.Component { constructor(props){ super(props); this.state = {date: new Date()}; //state 用來記錄狀態(tài) } render(){ return (); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, //刪除參數(shù) document.getElementById("root") );
為了控制計(jì)時(shí)的生命周期,我們需要引入 2 個(gè)方法 componentDidMount() 和 componentWillUnmount(),前者在渲染(render方法)完成時(shí)立即執(zhí)行,后者在該 render 的內(nèi)容即將被移除前執(zhí)行。
很明顯,前者適合注冊(cè)計(jì)時(shí)器,后者可以用來清除計(jì)時(shí)器(防止內(nèi)存泄露)
componentDidMount(){ this.timerID = setInterval( () => this.tick(), 1000 ); } componentWillUnmount(){ clearInterval(this.timerID); }
下一步我們重寫 tick 函數(shù),此時(shí)的 tick 函數(shù)只需要修改 this.state 就行了。注意 React 要求不能直接修改該屬性,而是使用 setState() 方法,所以 tick 函數(shù)如下:
tick(){ this.setState({ date: new Date() }); }
這里需要注意的是,當(dāng) state 中有很多屬性的時(shí)候,比如:
this.state = {name:"Lily", age: 12};執(zhí)行 setState 方法修改其中的內(nèi)容時(shí)并不會(huì)影響未修改的屬性:
this.setState({name: "Bob"}); //此后 this.state 為 {name:"Bob", age: 12};此外 setState 可能是異步的,所以不要在更新狀態(tài)時(shí)依賴前值:
// 這是個(gè)反例 this.setState({ counter: this.state.counter + this.props.increment, });為例解決這個(gè)問題,你可以傳入函數(shù)參數(shù):
// Correct
this.setState((prevState, props) => ({ //這里 prevState 更新前的 state 對(duì)象,props 為新值構(gòu)成的對(duì)象
counter: prevState.counter + props.increment
}));
此時(shí),完整的代碼為:
class 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 (事件); } } ReactDOM.render(Hello, world!
It is {this.state.date.toLocaleTimeString()}.
, document.getElementById("root") );
React 事件注冊(cè)和原生 DOM 事件類似的,這里需要理解一些不同點(diǎn)即可:
事件名使用小駝峰寫法,而不是全小寫,例如:onclick 寫作 onClick
注冊(cè)事件使用花括號(hào)表達(dá)式替代原有函數(shù)寫法
無法通過事件函數(shù) return false 的方式阻止默認(rèn)事件,必須顯式的調(diào)用 preventDefault(),并且在使用時(shí)不用糾結(jié)瀏覽器兼容問題,React 已經(jīng)幫你處理好了
React 建議通常不需要通過 addEventListener 添加事件,只需要像上方代碼那樣在 render 時(shí)綁定事件即可
在 es6 語法的組件中注冊(cè)事件只需要將事件函數(shù)定義為該類的一個(gè)方法,然后在 render 時(shí)綁定即可:
render(){ return ( ); }
在 class 中,除了箭頭函數(shù)定義的方法中 this 符合預(yù)期,其余方法中的 this 都是 undefined,應(yīng)該手動(dòng)綁定。因此以下三個(gè)按鈕中 click2 會(huì)報(bào)錯(cuò)。
class Button extends React.Component { constructor(){ super(); this.name = "Bob"; this.click3 = this.click2.bind(this); this.click1 = () => { console.log(`hello ${this.name}`); } } click2(){ console.log(`hello ${this.name}`); } render(){ return (); } }
以上幾種方法,React 推薦使用 click3 的實(shí)現(xiàn)方法,重寫如下:
class Button extends React.Component { constructor(){ super(); this.name = "Bob"; this.click = this.click.bind(this); } click(){ console.log(`hello ${this.name}`); } render(){ return (); } }
傳遞參數(shù)給事件的時(shí)候,第一個(gè)參數(shù)為 id, 第二個(gè)參數(shù)為 event。實(shí)際調(diào)用可以去以下兩種方式:
以上兩種方法等效,后一個(gè)方法的參數(shù) e 可以省略。
條件渲染根據(jù)不同的條件(通常指state)渲染不同的內(nèi)容, 比如下面段代碼可以根據(jù) isLoggenIn 渲染不同的問候語:
function UserGreeting(props) { returnWelcome back!
; } function GuestGreeting(props) { returnPlease sign up.
; } function Greeting(props) { const isLoggedIn = props.isLoggedIn; if (isLoggedIn) { // 根據(jù) isLoggenIn 渲染不同的問候語 return; } return ; } ReactDOM.render( // 你可以嘗試設(shè)置 isLoggedIn={true}: , document.getElementById("root") );
下面用 class 實(shí)現(xiàn)一個(gè)復(fù)雜一點(diǎn)的,帶有登錄/注銷按鈕的:
function LoginButton(props) { return ( ); } function LogoutButton(props) { return ( ); } class LoginControl extends React.Component { constructor(props) { super(props); this.state = { isLoggedIn: false }; // 修正 this 綁定 this.handleLoginClick = this.handleLoginClick.bind(this); this.handleLogoutClick = this.handleLogoutClick.bind(this); } handleLoginClick() { this.setState({isLoggedIn: true}); } handleLogoutClick() { this.setState({isLoggedIn: false}); } render() { const { isLoggedIn } = this.state; let button = null; if (isLoggedIn) { button =; } else { button = ; } return ( {/* Greeting 取自上一個(gè)示例 (注意這里的注釋寫法)*/}); } } ReactDOM.render({button} , document.getElementById("root") );
當(dāng)然,對(duì)于這樣一個(gè)簡(jiǎn)單的示例,使用 if 可能你會(huì)覺的太復(fù)雜了,我們也可以使用 && ?: 這些運(yùn)算符來代替 if 語句,就像寫 javascript 代碼一樣。我們極力的化簡(jiǎn)一下上面的代碼:
class LoginControl extends React.Component { constructor(props) { super(props); this.state = { isLoggedIn: false }; } render() { const { isLoggedIn } = this.state; const button = isLoggedIn ? : ; return (); } } ReactDOM.render({ isLoggedIn ? "Welcome back!" : "Please sign up." }
{button}, document.getElementById("root") );
當(dāng)然,如果你需要在某個(gè)條件下不進(jìn)行渲染,那么直接輸出 null 即可,比如下面這個(gè)組件,在 props.warn 為 false 時(shí)不渲染任何內(nèi)容:
function WarningBanner(props) { if (!props.warn) { return null; } return (Warning!); }
需要注意的是,即便你輸出了 null, react 也會(huì)再渲染一次。同理,componentWillUpdate 和 componentDidUpdate 也會(huì)被調(diào)用。
列表在 React 中我們可以使用 map() 方法渲染列表,比如如下這個(gè)例子,將一組數(shù)據(jù)映射(map)為一組 dom:
const data = [1, 2, 3, 4, 5]; const listItems = data.map((item) =>
我們注意到這里我們給 li (即列表的每個(gè)元素)標(biāo)簽加了一個(gè) key 屬性,這個(gè) key 用來幫助 React 判斷哪個(gè)元素發(fā)生了改變、添加或移除。關(guān)于這個(gè) key 我們需要明白以下幾點(diǎn):
最好保證 key 是一個(gè)字符串,并且在該列表中唯一,如果你的數(shù)據(jù)中實(shí)在沒有唯一的 key 可以選擇,那么就使用數(shù)組的索引(index)吧(不推薦這樣)
值得注意的是,如果你不給每個(gè)元素指定一個(gè) key, react 會(huì)默認(rèn)使用索引(index)作為 key
key 的值只是給 React 起到類似暗示的作用,不會(huì)真正的傳遞給 dom, 所以如果你需要使用 key 的值,應(yīng)使用一個(gè)其它變量傳遞該值。
當(dāng)然,上面代碼我們也可以寫成 inline 的形式:
const data = [1, 2, 3, 4, 5]; ReactDOM.render(
表單的處理會(huì)和原生的 html 有一些區(qū)別,因?yàn)?React 可以很好的幫助你使用 js 控制你的表單,這里我們需要引入一個(gè)新的概念:受控組件。
受控組件說白了就是其值受 react 控制的組件。其中,表單的元素通常都會(huì)具有其自己的 state,該值會(huì)隨著用戶的輸入改變。比如下面這個(gè)例子,會(huì)在用戶提交時(shí)輸出用戶的名字:
class NameForm extends React.Component { constructor(props) { super(props); this.state = {value: ""}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("A name was submitted: " + this.state.value); event.preventDefault(); } render() { return (); } }
不難發(fā)現(xiàn),這里使用了,onchange 事件不斷的將用戶的輸入綁定到 this.state.value 上,然后通過和用戶輸入同步的重繪實(shí)現(xiàn)數(shù)據(jù)的顯示。這樣可以很好的控制用戶輸入,比如同步的將用戶輸入轉(zhuǎn)化為大寫:
handleChange(event) { this.setState({value: event.target.value.toUpperCase()}); }
理解了上面的內(nèi)容我們可以知道,單純給一個(gè) input 賦值一個(gè)值用戶是不能修改的,比如下面這行代碼:
ReactDOM.render(, mountNode);
但如果你不小心他的值設(shè)為 null 或 undefined(等同于沒有 value 屬性),這個(gè) input 就可以被更改了:
ReactDOM.render(, mountNode); setTimeout(function() { ReactDOM.render(, mountNode); }, 1000);
在 React 中 textarea 也是通過 value 屬性實(shí)現(xiàn)其內(nèi)容變化的,而非其子節(jié)點(diǎn):
class EssayForm extends React.Component { constructor(props) { super(props); this.state = { value: "Please write an essay about your favorite DOM element." }; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("An essay was submitted: " + this.state.value); event.preventDefault(); } render() { return (); } }
在 React 中,對(duì)于 select 也會(huì)顯得很方便,你不需要在 option 中通過 selected 改變其值了,而是在 select 標(biāo)簽上通過 value 屬性實(shí)現(xiàn):
class FlavorForm extends React.Component { constructor(props) { super(props); this.state = {value: "coconut"}; this.handleChange = this.handleChange.bind(this); this.handleSubmit = this.handleSubmit.bind(this); } handleChange(event) { this.setState({value: event.target.value}); } handleSubmit(event) { alert("Your favorite flavor is: " + this.state.value); event.preventDefault(); } render() { return (); } }
上面代碼默認(rèn)選中 Coconut。 這里值得注意的是,對(duì)于多選框,你可以傳入一個(gè)數(shù)組作為值:
當(dāng)你控制很多個(gè)表單組件的時(shí)候要是為每個(gè)組件寫一個(gè) handler 方法作為 onChange 事件那就太麻煩了。所以 React 可以通過表單元素的 name 配合 event.target.name 來控制表單:
class Reservation extends React.Component { constructor(props) { super(props); this.state = { isGoing: true, numberOfGuests: 2 }; this.handleInputChange = this.handleInputChange.bind(this); } handleInputChange(event) { const { target } = event; const value = target.type === "checkbox" ? target.checked : target.value; const { name } = target; this.setState({ [name]: value }); } render() { return (); } } state 提升
這個(gè)部分,想說的不是個(gè)語法問題,而是代碼結(jié)構(gòu)問題。我們重點(diǎn)理解一個(gè)例子:計(jì)算溫度的功能。
我們實(shí)現(xiàn)2個(gè)輸入框(攝氏溫度和華氏溫度)的同步數(shù)據(jù)顯示,和對(duì)數(shù)據(jù)的簡(jiǎn)單操作(判斷是否達(dá)到標(biāo)況下水的沸點(diǎn)100攝氏度)
我們先做點(diǎn)準(zhǔn)備工作,比如溫度轉(zhuǎn)換函數(shù):
function toCelsius(fahrenheit) { return (fahrenheit - 32) * 5 / 9; } function toFahrenheit(celsius) { return (celsius * 9 / 5) + 32; }
別忘了,一個(gè)好的程序員要能夠很好的控制數(shù)據(jù)輸入,所以我們?cè)賹懸粋€(gè)函數(shù)用來處理溫度,參數(shù)是溫度和溫度轉(zhuǎn)換函數(shù):
function tryConvert(temperature, convert) { const input = parseFloat(temperature); if (Number.isNaN(input) || typeof convert !== "function") { return ""; } const output = convert(input); const rounded = Math.round(output * 1000) / 1000; return String(rounded); }
我們先簡(jiǎn)單實(shí)現(xiàn)這個(gè)功能:
function BoilingVerdict(props) { if (props.celsius >= 100) { returnThe water would boil.
; } returnThe water would not boil.
; }
然后我們寫一個(gè)組件用來讓用戶輸入溫度
class Calculator extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {temperature: ""}; } handleChange(e) { this.setState({temperature: e.target.value}); } render() { const { temperature } = this.state; return (); } }
此時(shí)我們可以輸入攝氏溫度了,再添加一個(gè)數(shù)據(jù)華氏溫度的地方。這里我們從上面的 Calculator 中提出來輸入組件:
const scaleNames = { c: "Celsius", f: "Fahrenheit" }; class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.state = {temperature: ""}; } handleChange(e) { this.setState({temperature: e.target.value}); } render() { const { temperature } = this.state; const { scale } = this.props; return (); } }
這樣 Calculator 就簡(jiǎn)單了:
class Calculator extends React.Component { render() { return (); } }
這樣2個(gè)輸入框就有了,但是它們還不能同步變化。而且 Calculator 組件不知道水溫是多少了,沒法判斷溫度了。這是我們應(yīng)該吧溫度狀態(tài)放在他們最近的公共祖先元素上,這里就是 Calculator 組件啦。
很明顯,首先要改的就是 TemperatureInput, 它不需要 state 了,我們應(yīng)該從參數(shù)獲取溫度了:
class TemperatureInput extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); } handleChange(e) { this.props.onTemperatureChange(e.target.value); } render() { const { temperature, scale } = this.props; return (); } }
之后我們修改 Calculator 的 state, 將 temperature 和 scale 放入其中, 并添加狀態(tài)轉(zhuǎn)換函數(shù):
class Calculator extends React.Component { constructor(props) { super(props); this.handleCelsiusChange = this.handleCelsiusChange.bind(this); this.handleFahrenheitChange = this.handleFahrenheitChange.bind(this); this.state = {temperature: "", scale: "c"}; } handleCelsiusChange(temperature) { this.setState({scale: "c", temperature}); } handleFahrenheitChange(temperature) { this.setState({scale: "f", temperature}); } render() { const { temperature, scale } = this.state; const celsius = scale === "f" ? tryConvert(temperature, toCelsius) : temperature; const fahrenheit = scale === "c" ? tryConvert(temperature, toFahrenheit) : temperature; return (); } }
到此所有的工作就完成了。我們總結(jié)一下,輸入數(shù)據(jù)時(shí)都發(fā)生了什么
當(dāng)用戶輸入時(shí),react 調(diào)用了已經(jīng)申明的函數(shù)作為 onChange 事件。在這個(gè)例子中,就是 TemperatureInput 中的 handleChange 方法。
TemperatureInput 中的 handleChange 方法調(diào)用了 this.props.onTemperatureChange(), 并傳入了最新的值。而這個(gè)方法由父組件 Calculator 提供。
在前一次渲染中,Calculator 已經(jīng)將 Celsius TemperatureInput 的 onTemperatureChange 設(shè)置為 handleCelsiusChange,并將 Fahrenheit TemperatureInput 的 onTemperatureChange 設(shè)置為 handleFahrenheitChange。所以這兩個(gè)計(jì)算方法的調(diào)用取決于我們編輯哪一個(gè) input。
在這兩個(gè)方法中,Calculator 組件通過調(diào)用 this.setState() 方法讓 react 以最新的輸入和當(dāng)前 scale 重繪該組件。
React 調(diào)用 Calculator 組件的 render 方法渲染頁面,兩個(gè) input 中的值會(huì)基于當(dāng)前值和 scale 重新計(jì)算, 溫度轉(zhuǎn)換函數(shù)就是在這里被調(diào)用的。
React 通過 props 使用 Calculator 新傳入的數(shù)據(jù),分別調(diào)用每個(gè) TemperatureInput 模塊中的 render 方法渲染 input 組件。
React DOM 更新 DOM 樹匹配新的數(shù)據(jù),我們編輯的 input 得到我們剛剛輸入的值,而另一個(gè) input 得到轉(zhuǎn)換后的值。
我們看看官方給出的效果:
組合與繼承React 建議用組件組合的方式代替組件繼承。所以我們需要學(xué)習(xí)如何用組合代替繼承。
很多組件在事先是不知道自己的孩子(內(nèi)部的元素)的。比如對(duì)話框這樣的盒子型元素。我們需要使用 children 屬性來解決這個(gè)問題
function FancyBorder(props) { return ({props.children}); }
props.children 表示通過其他組件調(diào)用 FancyBorder 時(shí)的全部孩子元素,對(duì)應(yīng)下面例子,children 就是 h1 和 p 的 react 對(duì)象數(shù)組
function WelcomeDialog() { return (); } Welcome
Thank you for visiting our spacecraft!
但是當(dāng)組件缺乏共同點(diǎn)的時(shí)候,我們需要在組件中開很多孔,就像下面這個(gè)例子,這些孔可以很好的幫我們組合使用很多組件,而且 react 并不限制我我們傳遞參數(shù)的類型
function SplitPane(props) { return (); } function App() { return ({props.left}{props.right}} right={ } /> ); }
有時(shí)候我們想對(duì)組件做具體化分類的時(shí)候,邏輯上會(huì)很像繼承,比如 WelcomeDialog 是 Dialog 的一個(gè)具體化分類。但在 React 中我們依然用組合的方式實(shí)現(xiàn)這個(gè)功能:
function Dialog(props) { return (); } function WelcomeDialog() { return ( ); } {props.title}
{props.message}
當(dāng)然我們也可以用 class 的定義方式:
function Dialog(props) { return (); } class SignUpDialog extends React.Component { constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleSignUp = this.handleSignUp.bind(this); this.state = {login: ""}; } render() { return ( ); } handleChange(e) { this.setState({login: e.target.value}); } handleSignUp() { alert(`Welcome aboard, ${this.state.login}!`); } } {props.title}
{props.message}
{props.children}
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97630.html
摘要:考慮到是快速入門,于是乎我們就記住一點(diǎn),當(dāng)修改值需要重新渲染的時(shí)候,的機(jī)制是不會(huì)讓他全部重新渲染的,它只會(huì)把你修改值所在的重新更新。這一生命周期返回的任何值將會(huì)作為參數(shù)被傳遞給。 安裝react npm install creat-react-app -gshowImg(https://segmentfault.com/img/remote/1460000015639868); 這里直...
摘要:一份開發(fā)者必備的技能清單,請(qǐng)查收。入門查漏補(bǔ)缺深入學(xué)習(xí)查看原圖下載源文件使用快速上手,并了解其中的概念。官方教程入門教程小書文章精讀,問題解答。 一份react開發(fā)者必備的技能清單,請(qǐng)查收。入門、查漏補(bǔ)缺、深入學(xué)習(xí)... showImg(https://segmentfault.com/img/remote/1460000018000950?w=1965&h=3332); 查看原圖 ...
摘要:本篇解釋中類的控制指令,與指令式界面設(shè)計(jì)相關(guān)。本專欄歷史文章介紹一項(xiàng)讓可以與抗衡的技術(shù)可視化開發(fā)工具非正經(jīng)入門之一三宗罪可視化開發(fā)工具非正經(jīng)入門之二分離界面設(shè)計(jì)可視化開發(fā)工具非正經(jīng)入門之三雙源屬性與數(shù)據(jù)驅(qū)動(dòng)可視化開發(fā)工具非正經(jīng)入門之四 本系列博文從 Shadow Widget 作者的視角,解釋該框架的設(shè)計(jì)要點(diǎn)。本篇解釋 Shadow Widget 中類 Vue 的控制指令,與指令式界面...
摘要:今年以來,的文檔更新很快完善社區(qū)也日漸狀大,再加上于某廠你懂的大力的推廣,的前景十分光明。一般情況下,中小型的系統(tǒng)從遷移到版本大概只需要天的時(shí)間。快去動(dòng)手嘗試吧原創(chuàng)新書移動(dòng)前端高效開發(fā)實(shí)戰(zhàn)已在亞馬遜京東當(dāng)當(dāng)開售。 作者:曉飛(滬江Web前端開發(fā)工程師)本文原創(chuàng),轉(zhuǎn)載請(qǐng)注明作者及出處 Vue.js框架已經(jīng)火了好長(zhǎng)一段時(shí)間了,早在2015年的雙11中,淘寶的部分導(dǎo)購業(yè)務(wù)——如:雙十一晚會(huì)搖...
摘要:一團(tuán)隊(duì)組織網(wǎng)站說明騰訊團(tuán)隊(duì)騰訊前端團(tuán)隊(duì),代表作品,致力于前端技術(shù)的研究騰訊社交用戶體驗(yàn)設(shè)計(jì),簡(jiǎn)稱,騰訊設(shè)計(jì)團(tuán)隊(duì)網(wǎng)站騰訊用戶研究與體驗(yàn)設(shè)計(jì)部百度前端研發(fā)部出品淘寶前端團(tuán)隊(duì)用技術(shù)為體驗(yàn)提供無限可能凹凸實(shí)驗(yàn)室京東用戶體驗(yàn)設(shè)計(jì)部出品奇舞團(tuán)奇虎旗下前 一、團(tuán)隊(duì)組織 網(wǎng)站 說明 騰訊 AlloyTeam 團(tuán)隊(duì) 騰訊Web前端團(tuán)隊(duì),代表作品WebQQ,致力于前端技術(shù)的研究 ISUX 騰...
閱讀 2173·2021-09-04 16:40
閱讀 1471·2021-08-13 15:07
閱讀 3612·2019-08-30 15:53
閱讀 3203·2019-08-30 13:11
閱讀 1082·2019-08-29 17:22
閱讀 1821·2019-08-29 12:47
閱讀 1481·2019-08-29 11:27
閱讀 2235·2019-08-26 18:42