18. react - 父子元件傳參
阿新 • • 發佈:2020-10-28
1.父元件傳遞給子元件
通過props傳遞資料(狀態,方法)
2.子元件 ->父元件
通過props傳遞給子元件方法,子元件通過this.props.func呼叫父元件方法改變父元件狀態。
不同於 VUE沒有emit。
3.例項:
父元件:simpleCart.js
子元件:Cart.js
// simpleCart.js import React from 'react'; // 基於類的元件 匯入方式 import Cart from './Cart'; // 函式型別的元件 匯入方式 // import { Cart } from './Cart'; export defaultclass CartSample extends React.Component { // 狀態的初始化一般放在構造器中 constructor(props){ super(props); this.state = { text: '', goods: [], cartList: [] } this.textChange = this.textChange.bind(this) } // 當 input 的值 text 發生變化的時候,我們讓 textChang 去切換 input 的值textChange (event){ this.setState({text: event.target.value}) } addGoods = () => { this.setState(prevstate => { // react 官方希望傳入與返回的物件不應該是同一個物件 return { goods: [ ...prevstate.goods, { id: prevstate.goods.length+ 1, name: prevstate.text } ] } }) } // 加購 addToCart = (good) => { // 建立一個新的購物車列表 const newCartList = [ ...this.state.cartList ] // 根據 商品ID 判斷購物車內有無傳入的商品 const idx = newCartList.findIndex( c => c.id === good.id) // 找到該 idx 對應的商品 const item = newCartList[idx] if(item){ // 如果購物車內有該商品,則商品數量 +1 // 刪除 idx 項,再新增一項,新增項的屬性和 item 一樣,唯獨修改 count newCartList.splice(idx,1,{ ...item,count: item.count +1 }) }else{ // 如果購物車內沒有該商品 newCartList.push({...good,count:1}) } //更新 this.setState({cartList:newCartList}) } countChange = (good,type) =>{ const newCartList = [ ...this.state.cartList ] const idx = newCartList.findIndex( c => c.id === good.id) const item = newCartList[idx] // 購物車列表中肯定有該商品,因為不需要判斷 item 是否存在,只需要對 count 進行操作即可 if(type){// 有 type 即是 點選 + 按鈕,商品數量 +1 newCartList.splice(idx,1,{ ...item,count: item.count +1 }) }else{ // 否則就是點選 - 按鈕,商品數量 -1 newCartList.splice(idx,1,{ ...item,count: item.count -1 }) } this.setState({cartList:newCartList}) } render() { return ( <div style={cartStyle}> {/* 事件處理 */} <div> <input type="text" value={this.state.text} onChange={this.textChange}/> <button onClick={this.addGoods}>加入商品</button> </div> <h1>商品列表</h1> <ul> {this.state.goods.map((good) => ( <li key={good.id}> {good.name} {/* 新增 加購按鈕 */} <button onClick={() => this.addToCart(good)}>加入購物車</button> </li> ))} </ul> {/* 購物車 */} <h1>購物車列表</h1> {/* 通過 list 屬性吧購物車列表傳給 cart 元件 */} <Cart list={this.state.cartList} countChange={this.countChange}></Cart> </div> ); } } const cartStyle = { border: '1px solid #ddd', marginTop: '50px', background: 'rgba(80, 255, 20, 0.6)' }
//Cart.js import React from 'react'; class Cart extends React.Component { constructor (props) { super(props) } render () { return ( <table> <tbody> { this.props.list.map((item, i) => ( <tr key={i}> <td>名稱:{item.name}</td> <td>數量: <button onClick={() => this.props.countChange(item)}>-</button> {item.count} <button onClick={() => this.props.countChange(item,1)}>+</button> </td> </tr> ) ) } </tbody> </table> ) } } export default Cart