映射一个对象数组并在React中使用onClick更改值

时间:2017-12-04 08:14:10

标签: javascript reactjs

我尝试在使用map()列出每个obj时更改cardArr对象中的like值。

以下是我的代码。 当前,它工作,但每个对象共享相同的计数器,因为它没有从对象调用。我知道我目前只是调用存储在状态中的对象属性,但是如何使用map函数在每个对象中编辑类似?

import React, { Component } from 'react';

const cardArr = [
{
    id: 1,
    text: "Hey this is a test.",
    img: " ",
    like: 0
},
{
    id: 2,
    text: "If this works I'll call it a day.",
    img: " ",
    like: 0
},
{
    id: 3,
    text: "I'll drink a lot of beer.",
    img: " ",
    like: 0
},
{
    id: 4,
    text: "Cheers",
    img: " ",
    like: 0

}
]


export class Card extends Component {
    constructor(props) {
    super(props);
    this.state = {
      like: 0,
      show: true
    };
     // this.handleClick = this.handleClick.bind(this);


  }



IncrementItem = () => {
    this.setState({ like: this.state.like + 1 });
}
DecreaseItem = () => {
    this.setState({ like: this.state.like - 1 });
}

// handleClick(e) {
//  e.preventDefault();
//  this.IncrementItem();
// }
// handleClick(e) {
//  e.preventDefault();
//  this.DecreaseItem();
// }


render() {

    const cardList = (cardArr.map((card) => 

        <ul>
            <li>
            <div key={card.id}>
                {card.text};
                <img src={card.img}/>
                <p>Like Button</p>
                <button onClick={this.handleClickAdd}>Like</button>
                <p>Dilike Button</p>
                <button onClick={this.DecreaseItem}>Disike</button>
                <p>Likes: {this.state.like}</p>
            </div>
            </li>
        </ul>
        ));

    return(
        <div id='card'>
            {cardList}
        </div>
    )
}
}

3 个答案:

答案 0 :(得分:1)

而不是通过state中的喜欢,而是使用array,并根据id更新元素的内容。

import React, { Component } from 'react';

let cardArr = [
{
    id: 1,
    text: "Hey this is a test.",
    img: " ",
    like: 0
},
{
    id: 2,
    text: "If this works I'll call it a day.",
    img: " ",
    like: 0
},
{
    id: 3,
    text: "I'll drink a lot of beer.",
    img: " ",
    like: 0
},
{
    id: 4,
    text: "Cheers",
    img: " ",
    like: 0

}
]


export class Card extends Component {
    constructor(props) {
    super(props);
    this.state = {
       cardArr:cardArr 
    };
     // this.handleClick = this.handleClick.bind(this);


  }



IncrementItem = (id) => {
    let cards = this.state.cardArr;
    cards.find(c => c.id === id).like++;
    this.setState({cardArr:cards});
}
DecreaseItem = (id) => {
    let cards = this.state.cardArr;
    cards.find(c => c.id === id).like--;
    this.setState({cardArr:cards});
}  

render() {

    this.state.cardArr.map((card) => 

        <ul>
            <li>
            <div key={card.id}>
                {card.text};
                <img src={card.img}/>
                <p>Like Button</p>
                <button onClick={(card.id) => this.handleClickAdd(card.id)}>Like</button>
                <p>Dilike Button</p>
                <button onClick={(card.id) => this.DecreaseItem(card.id)}>Dislike</button>
                <p>Likes: {card.like}</p>
            </div>
            </li>
        </ul>
        );

    return(
        <div id='card'>
            {cardList}
        </div>
    )
}
}

答案 1 :(得分:1)

cardArr移动到组件的状态,以便在每个onClick(喜欢或喜欢)上,您可以根据需要更改like道具:

const Card = ({ card, onLike, onDeslike }) =>
  <div>
    {card.text}
    <p>Likes: {card.like}</p>
    <button onClick={() => onLike(card.id)}>Like</button>
    <button onClick={() => onDeslike(card.id)}>Deslike</button>
  </div>

class CardList extends React.Component {
  constructor(props) {
    super(props)

    this.state = {
      cards: [
        {
          id: 1,
          text: 'Hey this is a test.',
          img: ' ',
          like: 0,
        },
        {
          id: 2,
          text: "If this works I'll call it a day.",
          img: ' ',
          like: 0,
        },
        {
          id: 3,
          text: "I'll drink a lot of beer.",
          img: ' ',
          like: 0,
        },
        {
          id: 4,
          text: 'Cheers',
          img: ' ',
          like: 0,
        },
      ]
    }

    this.handleLike = this.handleLike.bind(this)
    this.handleDeslike = this.handleDeslike.bind(this)
  }

  handleLike(id) {
    this.setState(prevState => ({
      ...prevState,
      cards: prevState.cards.map(card => ({
        ...card,
        like: card.id === id ? card.like + 1 : card.like
      }))
    }))
  }

  handleDeslike(id) {
    this.setState(prevState => ({
      ...prevState,
      cards: prevState.cards.map(card => ({
        ...card,
        like: card.id === id ? card.like - 1 : card.like
     }))
    }))
  }

  render() {
    return (
      <div>
        <ul>
          {this.state.cards.map(card =>
            <li key={card.id}>
              <Card
                card={card}
                onLike={this.handleLike}
                onDeslike={this.handleDeslike}
              />
            </li>
          )}
        </ul>
      </div>
    )
  }
}

ReactDOM.render(
  <CardList />,
  document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

不要忘记setState是异步的,因此,您不会立即获得最新更改。

答案 2 :(得分:1)

如何分离。为cardAddr创建其他组件。并将渲染和like工作逻辑移动到CardAddr组件。

const cardArr = [
{
    id: 1,
    text: "Hey this is a test.",
    img: " ",
    like: 0
},
{
    id: 2,
    text: "If this works I'll call it a day.",
    img: " ",
    like: 0
},
{
    id: 3,
    text: "I'll drink a lot of beer.",
    img: " ",
    like: 0
},
{
    id: 4,
    text: "Cheers",
    img: " ",
    like: 0

}]

class CardAddr extends React.Component {
    constructor(props) {
    super(props);
    this.state = this.state = props.card;
  }
   
  IncrementItem = () => {
    this.setState({ like: this.state.like + 1 });
  }
  DecreaseItem = () => {
    this.setState({ like: this.state.like - 1 });
  }
  
  render() {
  	return (
        <div key={this.state.id}>
            {this.state.text}
            <img src={this.state.img}/>
            <p>Like Button</p>
            <button onClick={this.IncrementItem}>Like</button>
            <p>Dilike Button</p>
            <button onClick={this.DecreaseItem}>Disike</button>
            <p>Likes: {this.state.like}</p>
        </div>
    )
  }
}

class Card extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      show: true
    };
  }

render() {
    const cardList = (cardArr.map((card) => 
        <ul key={card.id}>
            <li>
              <CardAddr card={card}/>
            </li>
        </ul>
    ));

    return(
        <div id='card'>
            {cardList}
        </div>
    )
}
}

ReactDOM.render(
  <Card />,
  document.getElementById('container')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container">
    
</div>