您好,欢迎来到花图问答。
搜索
您的当前位置:首页[fullstack react #1] 父子组件属性和状态的传

[fullstack react #1] 父子组件属性和状态的传

来源:花图问答

使用ES7 class语法,bootstrapV4作为css样式

Voting Example.png

父组件

// 父组件 ProductsList.js
import React, { Component } from 'react';
import Product from './Product';

const products = [
  { 
    id: 1,
    imgUrl: 
    title: 'apple pie', 
    description: 'an apple a day keep a doctor away', 
    votes: 55
  },
  { 
    id: 2,
    imgUrl: 
    title: 'orange juice', 
    description: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Id saepe,
 ratione veritatis debitis minima, alias explicabo. Possimus nostrum consequuntur
 dolorum, rem ipsum cupiditate expedita eligendi, iure temporibus odit quaerat minus.', 
    votes: 12
  },
  { 
    id: 3,
    imgUrl: 
    title: 'time machine', 
    description: 'how to make a time machine, so we can go back and look forward', 
    votes: 66
  },
  { 
    id: 4,
    imgUrl: 
    title: 'big bang of throey', 
    description: 'why stephen is so funny guy', 
    votes: 8
  }
]

export default class ProductsList extends Component {
    state = { // 状态
        products: products
    }

    handleVoteUp = (productId) => { // 处理子组件上的自定义 'onVoteUp' 事件
        const nextProducts = this.state.products.map((product) => {
            if (product.id === productId) { // 根据 id 来判断是哪个组件发生该事件
                return { ...product, votes: product.votes + 1 }
            } else {
                return product;
            }
        });
        this.setState({
            products: nextProducts
        });
    }

    handleVoteDown = (productId) => { // 处理子组件上的自定义 'onVoteDown' 事件
        const nextProducts = this.state.products.map((product) => {
            if (product.id === productId) {
                return { ...product, votes: product.votes - 1 }
            } else {
                return product;
            }
        });
        this.setState({
            products: nextProducts
        });
    }

    render() {
        const productsList = this.state.products.map(product => (
                       // Product子组件 及 子组件上的属性
            <Product
                key={'product-' + product.id}
                id={product.id}
                imgUrl={product.imgUrl}
                title={product.title}
                description={product.description}
                votes={product.votes}
                onVoteUp={this.handleVoteUp}
                onVoteDown={this.handleVoteDown}
            />
        ));
        return (
            <ul className="list-unstyled" style={{width: 800}}>
                { productsList }
            </ul>
        )
    }
}

子组件

// 父组件以属性的形式,将状态传递给子组件
// Product.js
import React, { Component } from 'react';

export default class Product extends Component {

    voteUp = () => { // click 事件的handler
        this.props.onVoteUp(this.props.id) // 调用属性上的 'onVoteUp' 方法
    }

    voteDown = () => {
        this.props.onVoteDown(this.props.id) // 调用属性上的 'onVoteDown 方法
    }

    render() {
        const { imgUrl, title, description, votes } = this.props;
        return (
            <li className="media" style={{marginTop: 20}}>
              <img className="d-flex mr-3" src={imgUrl} alt="image"/>
              <div className="media-body">
                <h5 className="mt-0">{ title }</h5>
                { description }

                <div>
                    { votes }
                    <button onClick={this.voteUp}>投票 UP</button>
                    <button onClick={this.voteDown}>投票 DOWN</button>
                </div>
              </div>
            </li>
        )
    }
}

app.js

import React, { Component } from 'react';
import ProductsList from './ProductsList';

class App extends Component {
  render() {
    return (
      <ProductsList />
    );
  }
}

export default App;

Copyright © 2019- huatuowenda.com 版权所有 湘ICP备2023022495号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务