2016-06-13 38 views
0

我幾天前纔開始學習React,所以請原諒我,如果這個問題聽起來真的很愚蠢。從材質-Ui的GridList中提取屬性

在這項工作任務中,我必須使用material-ui的GridList實現一個'Like'系統。總共有8張圖片,用戶可以通過點擊按鈕來喜歡它們。在我目前的代碼中,用戶可以點擊類似的按鈕,但所有類似的按鈕將受到影響,而不僅僅是一個。此外,喜歡的數量不會增加。

所以我的問題是,當用戶點擊'Like'按鈕並確保只有1個按鈕受到影響時,如何更改喜歡的數量?我已經嘗試過道具甚至連衣裙,但我似乎無法弄清楚問題所在。以下是我的整個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, 
} 

回答

0

問題

按鈕被循環外定義的「狀態」是指相同的「狀態」與所有GridTile成分(所有圖片)共享。

當點擊了「喜歡」按鈕,然後要更改的「喜歡」在父組件的按鈕,是網格和相同「狀態」被用於所有按鈕的「狀態」。

這就是爲什麼它影響所有按鈕。

'狀態' 應該分別爲每個按鈕來定義。另外刪除方法應該在GridTile的循環內部定義。

但是GridTile是material-ui庫的一部分,所以不是改變這個庫,而是在GridTile組件上創建一個包裝。 網格組件將調用組件讓它說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, 
    }