在文字輸入一些文字,然後按增加,就會到 radio button 的上面
※先寫靜態
class App extends React.Component { constructor(p) { super(p) } render() { return ( <div> <h1>Component 組合練習</h1> <Add /> <RadioList /> </div> ) } } class Add extends React.Component { constructor(p) { super(p) this.handleAdd = this.handleAdd.bind(this) } handleAdd() { const txt = this.txt.value.trim(); if(!txt){ return } } render() { return ( <div> <input ref={i => this.txt = i}/> <button onClick={this.handleAdd}>增加#5</button> </div> ) } } const xxx = ["a", "b", "c"]; class RadioList extends React.Component { constructor(p) { super(p) } render() { return ( <ul> { xxx.map((data, i) => <li key={i}><input type="radio" name="x" />{data}</li>) } </ul> ) } } ReactDOM.render(<App />, document.querySelector("#div1"));※
※再寫動態
class App extends React.Component { constructor(p) { super(p) this.state = { data:["a", "b", "c"] } } render() { return ( <div> <h1>Component 組合練習</h1> <Add count={this.state.data.length} /> <RadioList data={this.state.data} /> </div> ) } } class Add extends React.Component { constructor(p) { super(p) this.handleAdd = this.handleAdd.bind(this) } handleAdd() { const txt = this.txt.value.trim() if(!txt) { return } console.log(txt) } render() { return ( <div> <input ref={i => this.txt = i}/> <button onClick={this.handleAdd}>增加#{this.props.count + 1}</button> </div> ) } } Add.propTypes = { count : PropTypes.number.isRequired } // const xxx = ["a", "b", "c"]; class RadioList extends React.Component { constructor(p) { super(p) } render() { return ( <ul> { this.props.data.map((data, i) => { return <li key={i}><input type="radio" name="x" />{data}</li> }) } </ul> ) } } RadioList.propTypes = { data : PropTypes.array.isRequired } ReactDOM.render(<App />, document.querySelector("#div1"));※
※互動
class App extends React.Component { constructor(p) { super(p) this.state = { data:["a", "b", "c"] } this.addNewData = this.addNewData.bind(this) } addNewData(newData) { this.state.data.unshift(newData) this.setState({data : this.state.data}) } render() { return ( <div> <h1>Component 組合練習</h1> <Add count={this.state.data.length} addNewData={this.addNewData} /> <RadioList data={this.state.data} /> </div> ) } } class Add extends React.Component { constructor(p) { super(p) this.handleAdd = this.handleAdd.bind(this) } handleAdd() { const txt = this.txt.value.trim() if(!txt) { return } this.props.addNewData(txt) this.txt.value = '' } render() { return ( <div> <input ref={i => this.txt = i}/> <button onClick={this.handleAdd}>增加#{this.props.count + 1}</button> </div> ) } } Add.propTypes = { count : PropTypes.number.isRequired, addNewData : PropTypes.func.isRequired } class RadioList extends React.Component { constructor(p) { super(p) } render() { return ( <ul> { this.props.data.map((data, i) => { return <li key={i}><input type="radio" name="x" />{data}</li> }) } </ul> ) } } RadioList.propTypes = { data : PropTypes.array.isRequired } ReactDOM.render(<App />, document.querySelector("#div1"));
※由於子組件不能使用 this.state 改變父組件的狀態
而狀態在哪一個組件,this.state 就寫在哪
所以傳一個 function 給子組件調用
※簡化並整理代碼
class App extends React.Component { state = { data:["a", "b", "c"] } addNewData = (newData) => { const {data} = this.state data.unshift(newData) this.setState({data}) } render() { const {data} = this.state; return ( <div> <h1>Component 組合練習</h1> <Add count={data.length} addNewData={this.addNewData} /> <RadioList data={data} /> </div> ) } } class Add extends React.Component { static propTypes = { count : PropTypes.number.isRequired, addNewData : PropTypes.func.isRequired } handleAdd = _ => { const txt = this.txt.value.trim() if(!txt) { return } this.props.addNewData(txt) this.txt.value = '' } render() { return ( <div> <input ref={i => this.txt = i}/> <button onClick={this.handleAdd}> 增加#{this.props.count + 1} </button> </div> ) } } class RadioList extends React.Component { static propTypes = { data : PropTypes.array.isRequired } render() { const {data} = this.props return ( <ul> { data.map((data, i) => { return ( <li key={i}> <input type="radio" name="x" /> {data} </li> ) }) } </ul> ) } } ReactDOM.render(<App />, document.querySelector("#div1"));
※使用箭頭函數不用 bind
※this.state 寫在外面,是因為繼承了 React.Component 才可以這麼做,ES6 不可以
※propTypes 寫在類別裡
※修改成解構賦值,以下是原理:
const {a} = {a:1} console.log(a); // 1 const {b, c} = {b:2, c:3} console.log(b, c); // 2, 3 const ooo = {d:4} const {d} = ooo; console.log(d); // 4 const xxx = {e:5, f:6} const {e, f} = xxx; console.log(e, f); // 5, 6
※ooo 和 xxx 就好比是 this.state
※pubsub-js
可以在全域宣告,可以解決上面的傳 func 的問題,父子間、兄弟間傳參都很麻煩,可以用這種辦法解決,官網連結www.bootcdn.cn 的下載點:https://cdn.bootcss.com/pubsub-js/1.6.0/pubsub.js
使用 Node.js:到專案路徑下,執行 yarn add pubsub-js
執行完可下 npm list pubsub-js 查看是否成功
然後使用 import PubSub from 'pubsub-js'; 即可
※
<title>PubSub練習</title> <script src="./js/development_16.3.2.js"></script> <script src="./js/dom.development_16.3.2.js"></script> <script src="./js/babel_7.0.0-beta.3.js"></script> <script src="pubsub_1.6.0.js"></script> <div id="div1"></div> <script type="text/babel"> class App extends React.Component { declare = _ => { PubSub.subscribe('xxx', (p1, p2) => { console.log("p1=" + p1, "p2=" + p2) // p1=xxx p2=xxxxx }); } trigger = _ => { PubSub.publish('xxx', 'xxxxx'); } noTrigger = _ => { PubSub.unsubscribe('xxx'); } render() { return ( <div> <h1>PubSub 練習</h1> <button onClick={this.declare}>宣告</button> <button onClick={this.trigger}>觸發</button> <button onClick={this.noTrigger}>不想再觸發</button> </div> ) } } ReactDOM.render(<App />, document.querySelector("#div1")); </script>
※還有很多小技巧,自行參考官網
※再次將組件簡化後的代碼
<script src="./js/development_16.3.2.js"></script> <script src="./js/dom.development_16.3.2.js"></script> <script src="./js/babel_7.0.0-beta.3.js"></script> <script src="prop-types.js"></script> <script src="pubsub_1.6.0.js"></script> <div id="div1"></div> <script type="text/babel"> class App extends React.Component { state = { data:["a", "b", "c"], declareXxx: _ => { PubSub.subscribe('xxx', (p1, newData) => { const {data} = this.state data.unshift(newData) this.setState({data}) }); } } render() { this.state.declareXxx(); const {data} = this.state; return ( <div> <h1>Component 組合練習</h1> <Add count={data.length} /> <RadioList data={data} /> </div> ) } } class Add extends React.Component { static propTypes = { count : PropTypes.number.isRequired, } handleAdd = _ => { const txt = this.txt.value.trim() if(!txt) { return } console.log(txt) PubSub.publish('xxx', txt); this.txt.value = '' } render() { return ( <div> <input ref={i => this.txt = i}/> <button onClick={this.handleAdd}> 增加#{this.props.count + 1} </button> </div> ) } } class RadioList extends React.Component { static propTypes = { data : PropTypes.array.isRequired } render() { const {data} = this.props return ( <ul> { data.map((data, i) => { return ( <li key={i}> <input type="radio" name="x" /> {data} </li> ) }) } </ul> ) } } ReactDOM.render(<App />, document.querySelector("#div1")); </script>
※
沒有留言:
張貼留言