<div id="demo"></div><!--html元素或需要被操作的元素--> <script type="text/babel"> /*創建標簽名字第一個字母大寫*/ var Helloworld = React.createClass({ render:function(){ return (<div>hello world</div>); } }); /*ReactDOM.render 是 React 的最基本方法,用於將模板(html,jsx,React.createElement等)轉為 HTML ,並插入指定的 DOM 節點。*/ ReactDOM.render(<Helloworld/>,document.getElementById('demo'),,function(){ console.log('執行成功之后的回調函數'); }); </script>
Demo1
<div id="app"></div> <div id="demo"></div> <script type="text/babel"> var Helloreact = React.createClass({ render:function(){ return (<div>hello react</div>); } }); var Helloworld = React.createClass({ render:function(){ var reacts = []; for(var i=0;i<10;i++){ reacts.push(<Helloreact key={'Helloreact'+i}/>); } return ( <div> <div>hello world</div> {reacts} </div>); } }); var demos = ['demo1','demo2','demo3']; ReactDOM.render( <Helloworld/>, document.getElementById("app"), function(){ console.log('success'); } ); ReactDOM.render( <div> {demos.map(function(demo){ return (<div key={'demo'+demo}>Hello {demo}</div>); }) } </div>,document.getElementById('demo'),function(){ console.log('success'); } ); </script>
Demo2
<div id="demo"></div> <script type="text/babel"> var ClickDemo = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ getInitialState:function(){ return {clickCount:0}; }, clickFun:function(){ /*this.setState是更新state中的參數,執行實時更新組件的方法*/ return this.setState({clickCount:this.state.clickCount + 1}); }, render:function(){ return ( <div> <div>共點擊了{this.state.clickCount}</div> <button onClick={this.clickFun}>點我</button> </div>); } }); ReactDOM.render(<ClickDemo/>,document.getElementById('demo')); </script>
Demo3
<div id="demo"></div> <script type="text/babel"> var MessageBox = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ getInitialState:function(){ return { isVisible:true, title:'你好react', subMessages:['碼代碼可以改變世界','碼代碼是上帝創造的鬼斧神工','碼代碼可以走向人生巔峰'] } }, render:function(){ /* <Helloreact messages={this.state.subMessages}/> 這是將當前組件中的state的subMessages數組傳入到Helloreact組件中去, messages是傳入props的屬性名 */ return ( <div> <div>{this.state.title}</div> <Helloreact messages={this.state.subMessages}/> </div> ) } }); var Helloreact = React.createClass({ /* 這是設置當前默認的messages數組,如果前面組件未傳入參數進來就取默認的 */ getDefaultProps:function(){ return {messages:['默認喜歡碼代碼']} }, render:function(){ /* React中的每一個組件,都包含有一個屬性(props),屬性主要是從父組件傳遞給子組件的,在組件內部,我們可以通過this.props獲取屬性對象 react官方認為,props應該是只讀的,不應該被修改。因為 React 不能幫你檢查屬性類型(propTypes)。這樣即使你的 屬性類型有錯誤也不能得到清晰的錯誤提示。 Props 應該被當作禁止修改的。修改 props 對象可能會導致預料之外的結果,所以最好不要去修改 props 對象。 */ var msgs = []; /* map():返回一個新的Array,每個元素為調用func的結果 forEach():沒有返回值,只是針對每個元素調用func */ this.props.messages.forEach(function(msg,index){ msgs.push(<p key={index}>碼農說:{msg}</p>); }); return (<div>{msgs}</div>); } }); ReactDOM.render(<MessageBox/>,document.getElementById('demo')); </script>
Demo4
<div id="demo"></div> <script type="text/babel"> var FormApp = React.createClass({ getInitialState:function(){ return { inputValue:'this is inputValue', }; }, changeFunc:function(e){ this.setState({ /*設置當前state中inputValue的值是該html元素對象的value值*/ inputValue:e.target.value }); }, submitFunc:function(e){ e.preventDefault();/*阻止默認事件*/ console.log('form is submiting......'); console.log(e); }, render:function(){ /* 表單屬性中defaultValue屬性和value的區別 defaultValue是默認值,第一次設置時生效,手動輸入值時允許被改變 value是當前input的值,手動輸入值不會被改變 如果需要改變當前value的值則需要使用onChange事件來改變其中this.state.inputValue的值 */ return ( <form onSubmit={this.submitFunc} action="" method="post"> <input type="text" defaultValue={this.state.inputValue}/><br/><br/><br/> <input type="text" onChange={this.changeFunc} value={this.state.inputValue}/><br/><br/><br/> <button type="submit">提交一下</button> </form> ); } }); ReactDOM.render(<FormApp/>,document.getElementById('demo')); </script>
Demo5
<div id="demo"></div> <script type="text/babel"> var FormApp = React.createClass({ getInitialState:function(){ return { inputValue:'this is inputValue', }; }, changeFunc:function(e){ this.setState({ /*設置當前state中inputValue的值是該html元素對象的value值*/ inputValue:e.target.value }); }, submitFunc:function(e){ e.preventDefault();/*阻止默認事件*/ console.log('form is submiting......'); /* ref是React中的一種屬性,當render函數返回某個組件的實例時,可以給render中的某個虛擬DOM節點添加一個ref屬性 ref 屬性 React 支持一種非常特殊的屬性,你可以用來綁定到 render() 輸出的任何組件上去。這個特殊的屬性允許你引用 render() 返回的相應的支撐實例 ( backing instance )。這樣就可以確保在任何時間總是拿到正確的實例。 下面4種方式都可以通過ref獲取真實DOM節點 var usernameDOM = this.refs.username.getDOMNode(); var usernameDOM = React.findDOMNode(this.refs.username); var usernameDOM = this.refs['username'].getDOMNode(); var usernameDOM = React.findDOMNode(this.refs['username']); */ console.log(this.refs['goodInput']);//返回dom節點 /*console.log(this.refs['goodInput'].getDOMNode());無法調用*/ console.log(this.refs['goodInput'].value);//返回input節點下的value值 }, render:function(){ /* 表單屬性中defaultValue屬性和value的區別 defaultValue是默認值,第一次設置時生效,手動輸入值時允許被改變 value是當前input的值,手動輸入值不會被改變 如果需要改變當前value的值則需要使用onChange事件來改變其中this.state.inputValue的值 */ return ( <form onSubmit={this.submitFunc} action="" method="post"> <input type="text" defaultValue={this.state.inputValue}/><br/><br/><br/> <input type="text" ref="goodInput" defaultValue={this.state.inputValue}/><br/><br/><br/> <button type="submit">提交一下</button> </form> ); } }); ReactDOM.render(<FormApp/>,document.getElementById('demo')); </script>
Demo6
<div id="demo"></div> <script type="text/babel"> var FormApp = React.createClass({ getInitialState:function(){ return { inputValue:'this is inputValue', radioValue:'C', textareaValue:'this is textareaValue' }; }, changeFunc:function(e){ this.setState({ /*設置當前state中inputValue的值是該html元素對象的value值*/ inputValue:e.target.value }); }, submitFunc:function(e){ e.preventDefault();/*阻止默認事件*/ console.log('form is submiting......'); /* ref是React中的一種屬性,當render函數返回某個組件的實例時,可以給render中的某個虛擬DOM節點添加一個ref屬性 ref 屬性 React 支持一種非常特殊的屬性,你可以用來綁定到 render() 輸出的任何組件上去。這個特殊的屬性允許你引用 render() 返回的相應的支撐實例 ( backing instance )。這樣就可以確保在任何時間總是拿到正確的實例。 下面4種方式都可以通過ref獲取真實DOM節點 var usernameDOM = this.refs.username.getDOMNode(); var usernameDOM = React.findDOMNode(this.refs.username); var usernameDOM = this.refs['username'].getDOMNode(); var usernameDOM = React.findDOMNode(this.refs['username']); */ /*console.log(this.refs['goodInput']);返回dom節點*/ /*console.log(this.refs['goodInput'].getDOMNode());無法調用*/ /*console.log(this.refs['goodInput'].value);返回input節點下的value值*/ var formData = { textInput:this.refs['goodInput'].value, radioInput:this.state.radioValue, textareaEle:this.refs['goodTextarea'].value } console.log(formData); }, changeRadio:function(e){ /** 每當radio改變時,設置其state屬性值,那嵌套標簽里加入一個函數, 子函數調用為this.props.func,標簽引用func={this.func} */ this.setState({ radioValue:e.target.value }) }, render:function(){ /* 表單屬性中defaultValue屬性和value的區別 defaultValue是默認值,第一次設置時生效,手動輸入值時允許被改變 value是當前input的值,手動輸入值不會被改變 如果需要改變當前value的值則需要使用onChange事件來改變其中this.state.inputValue的值 */ return ( <form onSubmit={this.submitFunc} action="" method="post"> <input type="text" ref="goodInput" defaultValue={this.state.inputValue}/><br/><br/><br/> <RadioBox ref="goodRadio" changeRadio={this.changeRadio}/> this is textarea<br/> <textarea ref="goodTextarea" name="goodTextarea" defaultValue={this.props.textareaValue}></textarea> <button type="submit">提交一下</button> </form> ); } }); var RadioBox = React.createClass({ render:function(){ return ( <span> A: <input type="radio" onChange={this.props.changeRadio} name="goodRadio" value="A" /><br/> B: <input type="radio" onChange={this.props.changeRadio} name="goodRadio" value="B" /><br/> C: <input type="radio" onChange={this.props.changeRadio} name="goodRadio" defaultChecked value="C" /><br/><br/> </span> ); } }); ReactDOM.render(<FormApp/>,document.getElementById('demo')); </script>
Demo7
<div id="demo"></div> <script type="text/babel"> /*雙向數據流*/ var TwodTataFlow = React.createClass({ /* LinkedStateMixin給你的React組件添加一個叫做linkState()的方法。linkState() 返回一個ReactLink對象,包含ReactState當前的值和一個用來改變它的回調函數。 ReactLink對象可以在樹中作為props被向上傳遞或者向下傳遞 */ /* 雙向綁定的使用: 組件需要mixins:引用LinkedStateMixin。它提供一個linkState方法。參數是state屬性 雙向綁定用valueLink={this.linkState(XX)} linkState方法返回一個對象,有一個value屬性,指定state的屬性。 還有一個requestChange回調方法,用來實現state的修改。參數是新值 可以理解成onchange的綁定方法。可以自己寫一個linkState對象, value是state.XX requestChange里用setState()來修改值。用valueLink={obj}來實現。 可以理解成this.linkState()實現的就是指定綁定值value 和change方法 valueLink屬性實現了linkstate.value綁定到value requestChange方法綁定onChange 可以創建一個this.linkState('XX') value={XX.value} onchange={fn}方法內 使用Xx.requestChange(e.target.value) */ mixins:[React.addons.LinkedStateMixin], getInitialState:function(){ return { messages:'react is very good', isReactBool:true } }, render:function(){ return ( <div> <h1>ME說:{this.state.messages}</h1> <h2>React is very good?{this.state.isReactBool?' yes':' no'}</h2> <input type='text' valueLink={this.linkState('messages')}/> </div> ); } }); /* 不帶ReactLink的LinkedStateMixin(ReactLink Without LinkedStateMixin) 這個在處理input text文本框時使用valueLink是在其內部聲明了一個 valueLink方法,等同於是將這個方法中執行的requestChange請求執行handleChange */ var WithoutMixin = React.createClass({ getInitialState:function(){ return {message:'Hello!'}; }, handleChange:function(newValue){ this.setState({message:newValue}); }, render:function(){ /*valuelink * 它實際上實現的是狀態的綁定和change事件的修改 * requestChange方法接收值來實現state的修改 */ var valueLink = { value:this.state.message, requestChange:this.handleChange }; return ( <div> <h1>{this.state.message}</h1> <input type="text" valueLink={valueLink} /> </div> ) } }); ReactDOM.render(<WithoutMixin/>,document.getElementById('demo')); </script>
Demo8
<div id="demo"></div> <script type="text/babel"> /*雙向數據流*/ /* valueLink和checkedLink可以一直往子級傳遞 子級傳遞給子級的傳遞方式是 <父級套用子級 定義的屬性名messageLink={this.linkState(state的Key)}/> 子級是 <ChildChildTag messageLink={this.props.messageLink} /> 子子級是 <input type="text" valueLink={this.props.messageLink}/> */ var TwodTataFlow = React.createClass({ mixins:[React.addons.LinkedStateMixin], getInitialState:function(){ return { messages:'react is very good', isReactBool:true } }, render:function(){ return ( <div> <h1>ME說:{this.state.messages}</h1> <h2>React is very good?{this.state.isReactBool?' yes':' no'}</h2> <input type='text' valueLink={this.linkState('messages')}/><br/><br/> 你的選擇是:{this.state.isReactBool?' yes':' no'} <input type='checkbox' checkedLink={this.linkState('isReactBool')}/> <br/><br/><br/> <ChildTag messageLink={this.linkState('messages')} checkLink={this.linkState('isReactBool')}/> </div> ); } }); var ChildTag = React.createClass({ render:function(){ return ( <div> <h3>這個是子組件</h3> {/* 子級繼續向下傳遞props時就需要以下方法,但有時候向下傳遞時是重復動作,因此props傳遞時可以{...this.props} <ChildChildTag messageLink={this.props.messageLink} checkLink={this.props.checkLink}/> {...this.props}類似於將對應的valueLink和checkedLink方法傳遞 */} <ChildChildTag {...this.props}/> </div> ) } }); var ChildChildTag = React.createClass({ render:function(){ return ( <div> <p>你想對我說什么?</p> <input type="text" valueLink={this.props.messageLink}/><br/><br/> <p>React是最好的語言</p> <input type="checkbox" checkedLink={this.props.checkLink}/> </div> ) } }); ReactDOM.render(<TwodTataFlow/>,document.getElementById('demo')); </script>
Demo9
<div id="demo"></div> <script type="text/babel"> var Message = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ getInitialState:function(){ /* 在組件掛載之前調用一次。返回值將會作為 this.state 的初始值。 */ console.log('getInitialState'); return {titleMsg:'你好 React!',subMsg:'React是世界上最好的語言!',count:0}; }, getDefaultProps:function(){ /* 在組件類創建的時候調用一次,然后返回值被緩存下來。 如果父組件沒有指定 props 中的某個鍵,則此處返回的對象中的 相應屬性將會合並到 this.props (使用 in 檢測屬性)。 */ console.log('getDefaultProps'); }, componentWillMount:function(){ /* 服務器端和客戶端都只調用一次,在初始化渲染執行之前立刻調用。 如果在這個方法內調用 setState,render() 將會感知到更新后的 state, 將會執行僅一次,盡管 state 改變了。 */ console.log('componentWillMount'); /*這是在渲染之前的setState*/ // this.setState({titleMsg:'Hello React!'}); /*初始化之前設置一個定時器*/ var self = this; this.timer = setInterval(function(){ self.setState({count:self.state.count + 1}); },1000); }, componentDidMount:function(){ /* 在初始化渲染執行之后立刻調用一次,僅客戶端有效(服務器端不會調用)。 在生命周期中的這個時間點,組件擁有一個 DOM 展現, 你可以通過 this.getDOMNode() 來獲取相應 DOM 節點。 */ console.log('componentDidMount'); }, componentWillUnmount:function(){ console.log('組件被你刪掉了!'); /*組件刪除之后必須要停止對應的事件*/ clearInterval(this.timer); }, unmountFunc:function(){ /*ReactDOM.unmountComponentAtNode(Dom element)刪除節點操作*/ ReactDOM.unmountComponentAtNode(document.getElementById('demo')); }, render:function(){ if(this.state.count < 2){ console.log('渲染結束'); } return ( <div> <h1>{this.state.titleMsg}</h1> <h2>計時器:{this.state.count}</h2> <SubMessage {...this.state}/> <button onClick={this.unmountFunc}>點擊卸載整個組件</button> </div>); } }); var SubMessage = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ render:function(){ return ( <div> <h3>{this.props.subMsg}</h3> </div>); } }); ReactDOM.render(<Message/>,document.getElementById('demo')); </script>
Demo10
<div id="demo"></div> <script type="text/babel"> var Message = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ getInitialState:function(){ /* 在組件掛載之前調用一次。返回值將會作為 this.state 的初始值。 */ // console.log('getInitialState'); return {titleMsg:'你好 React!',subMsg:'React是世界上最好的語言!',count:0}; }, getDefaultProps:function(){ }, /*componentWillMount:function(){ }, componentDidMount:function(){ }, componentWillUnmount:function(){ },*/ shouldComponentUpdate:function(nextProp,nextState){ // console.log('shouldComponentUpdate'); // 假如下次更新時數值大於3時返回false,不讓更新 if(nextState.count > 10) return false; return true; }, componentWillUpdate:function(nextProp,nextState){ // console.log('componentWillUpdate'); }, componentDidUpdate:function(){ // console.log('componentDidUpdate'); }, unmountFunc:function(){ /*ReactDOM.unmountComponentAtNode(Dom element)刪除節點操作*/ ReactDOM.unmountComponentAtNode(document.getElementById('demo')); }, doUpdate:function(){ this.setState({count:this.state.count + 1}); }, render:function(){ return ( <div> <h1>{this.state.titleMsg}</h1> <h2>計時器:{this.state.count}</h2> <SubMessage {...this.state}/> <button onClick={this.doUpdate}>點一次+一次</button> {/*<button onClick={this.unmountFunc}>點擊卸載整個組件</button>*/} </div>); } }); var SubMessage = React.createClass({ /* 作用於組件的實例,在實例創建時調用一次,用於初始化每個實例的state,此時可以訪問this.props 組件之中的this.state可以調用了, */ /* 在組件接收到新的 props 的時候調用。在初始化渲染的時候,該方法不會調用。 用此函數可以作為 react 在 prop 傳入之后, render() 渲染之前更新 state 的機會。 老的 props 可以通過 this.props 獲取到。 在該函數中調用 this.setState() 將不會引起第二次渲染。 */ componentWillReceiveProps:function(nextProp){ // console.log('子組件將要獲取prop'); }, shouldComponentUpdate:function(nextProp,nextState){ /*子組件在被更新時控制其更新方式*/ if(nextProp.count > 5) return false; return true; }, render:function(){ return ( <div> <h3>{this.props.count}</h3> </div>); } }); ReactDOM.render(<Message/>,document.getElementById('demo')); </script>