在文字輸入一些文字,然後按增加,就會到 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>
※

沒有留言:
張貼留言