从material-ui的GridList中提取属性

时间:2016-06-13 03:20:42

标签: node.js reactjs material-ui

我几天前才开始学习React所以请原谅我,如果这个问题听起来很愚蠢。

在这项工作任务中,我必须使用material-ui的GridList实现一个'Like'系统。用户可以通过点击“赞”按钮共同观看八张图片。在我当前的代码中,用户可以点击“赞”按钮,但所有类似的按钮都会受到影响,而不仅仅是一个。此外,喜欢的数量不会增加。

所以我的问题是,当用户点击“赞”按钮并确保只有1个按钮受影响时,如何更改喜欢的数量?我试过道具甚至是lodash,但我似乎无法弄清楚问题。下面是我对GridList部分的整个代码。任何帮助将不胜感激。

import _ from 'lodash';
import React from 'react';
import {GridList, GridTile} from 'material-ui/GridList';
import Subheader from 'material-ui/Subheader';
import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
import getMuiTheme from 'material-ui/styles/getMuiTheme';

//GridList style
const styles = {
  root: {
    display: 'flex',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
  },
  gridList: {
    width: 1000,
    height: 500,
  },
};

//data for the GridList
var tilesData = [
  {
    img: './images/image_01.jpg',
    title: 'Breakfast',
    likes: 0,
  },
  {
    img: './images/image_02.jpg',
    title: 'Tasty burger',
    likes: 0,
  },
  {
    img: './images/image_03.jpg',
    title: 'Camera',
    likes: 0,
  },
  {
    img: './images/image_04.jpg',
    title: 'Morning',
    likes: 0,
  },
  {
    img: './images/image_05.jpg',
    title: 'Hats',
    likes: 0,
  },
  {
    img: './images/image_06.jpg',
    title: 'Honey',
    likes: 0,
  },
  {
    img: './images/image_07.jpg',
    title: 'Vegetables',
    likes: 0,
  },
  {
    img: './images/image_08.jpg',
    title: 'Water plant',
    likes: 0,
  },
];

export default class Grid extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      like: false,
      likes: tilesData.likes,
    };
    this.post = this.post.bind(this);
    this.delete = this.delete.bind(this);
  }

  //if Like button is clicked
  post(){
      this.setState({ like: true});
      let likes = this.state.likes;
      likes++;
      this.setState({likes: likes});
      //this.tilesData.likes = likes;
  }

  //if Like button is "unclicked"
  delete(){
      this.setState({ like: false});
      let likes = this.state.likes;
      likes--;
      this.setState({likes: likes});
      //this.tilesData.likes = likes;
  }

  getChildContext() {
    return { muiTheme: getMuiTheme(baseTheme) };
  }

  render(){
    const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
    return (
      <div style={styles.root}>
        <GridList
          cellHeight={200}
          cols={4}
          style={styles.gridList}
        >
        <Subheader>December</Subheader>
        {tilesData.map((tile) => (
          <GridTile
            key={tile.img}
            title={tile.title}
            subtitle={<span>Likes: <b>{tile.likes}</b></span>}
            actionIcon={likeBtn}
          >
            <img src={tile.img} />
          </GridTile>
          ))}
        </GridList>
      </div>
    );
  }
}

Grid.childContextTypes = {
  muiTheme: React.PropTypes.object.isRequired,
}

1 个答案:

答案 0 :(得分:0)

<强>问题

喜欢按钮的“状态”在循环外定义意味着所有 GridTile 组件共享“状态”(对于所有图像)。

当您点击“喜欢”按钮时,您正在更改“网格的父组件中的”喜欢“按钮的”状态“,并且所有类似的”状态“用于按钮。

这就是它影响所有喜欢按钮的原因。

<强>解决方案

'state'应该为每个按钮单独定义。此外,删除帖子方法应在GridTile中的循环方式内定义。

但是GridTile是material-ui库的一部分,所以不要改变这个库,而是在GridTile组件上创建一个包装器。 Grid组件将调用组件,让它在循环内部说GridTileCustom组件。

在GridTileCustom内部组件中,您需要定义在'onClick'事件中使用的删除发布方法 所以你的最终代码看起来像

import React from 'react';
  import {GridList, GridTile} from 'material-ui/GridList';
  import Subheader from 'material-ui/Subheader';
  import baseTheme from 'material-ui/styles/baseThemes/lightBaseTheme';
  import getMuiTheme from 'material-ui/styles/getMuiTheme';
  import IconButton from 'material-ui/IconButton';

  const thumbsIcon = "glyphicon glyphicon-thumbs-up";

  const styles = {
  root: {
    display: 'flex',
    flexWrap: 'wrap',
    justifyContent: 'space-around',
  },
  gridList: {
    width: 1000,
    height: 500,
  },
  };

  var tilesData = [
  {
    img: './images/image_01.jpg',
    title: 'Breakfast',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_02.jpg',
    title: 'Tasty burger',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_03.jpg',
    title: 'Camera',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_04.jpg',
    title: 'Morning',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_05.jpg',
    title: 'Hats',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_06.jpg',
    title: 'Honey',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_07.jpg',
    title: 'Vegetables',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  {
    img: './images/image_08.jpg',
    title: 'Water plant',
    likes: 0,
    icon: './images/icons/icon_1.png',
  },
  ];

  export default class Grid extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      like: false,
      likes: tilesData.likes,
    };
    // this.post = this.post.bind(this);
    // this.delete = this.delete.bind(this);
  }

  // post(){
  //     this.setState({ like: true});
  //     let likes = this.state.likes;
  //     likes++;
  //     this.setState({likes: likes});
  //     //this.tilesData.likes = likes;
  // }

  // delete(){
  //     this.setState({ like: false});
  //     let likes = this.state.likes;
  //     likes--;
  //     this.setState({likes: likes});
  //     //this.tilesData.likes = likes;
  // }

  getChildContext() {
    return { muiTheme: getMuiTheme(baseTheme) };
  }

  render(){
    return (
      <div style={styles.root}>
        <GridList
          cellHeight={200}
          cols={4}
          style={styles.gridList}
        >
        <Subheader>December</Subheader>
        {tilesData.map((tile) => (
          <GridTileInternal
            key={tile.img}
            img={tile.img}
            title={tile.title}
            subtitle={tile.likes}
            // actionIcon={likeBtn}
          >
          </GridTileInternal>
          ))}
        </GridList>
      </div>
    );
  }
  }

  class GridTileInternal extends React.Component {
  constructor(props){
    super(props);
    this.state = {
      like: false,
      likes: tilesData.likes,
    };
    this.post = this.post.bind(this);
    this.delete = this.delete.bind(this);
  }

  post(){
      this.setState({ like: true});
      let likes = this.state.likes;
      likes++;
      this.setState({likes: likes});
      //this.tilesData.likes = likes;
  }

  delete(){
      this.setState({ like: false});
      let likes = this.state.likes;
      likes--;
      this.setState({likes: likes});
      //this.tilesData.likes = likes;
  }


  render(){
    const likeBtn = this.state.like ? <img src="./images/icons/icon_2.png" onClick={this.delete} /> : <img src="./images/icons/icon_1.png" onClick={this.post} />;
    return (
          <GridTile
            key={this.props.img}
            title={this.props.title}
            subtitle={<span>Likes: <b>{this.props.subtitle}</b></span>}
            actionIcon={likeBtn}
          >
            <img src={this.props.img} />
          </GridTile>
    );
  }
  }

  Grid.childContextTypes = {
  muiTheme: React.PropTypes.object.isRequired,
  }