反应状态仅返回一个元素

时间:2019-12-17 10:10:29

标签: javascript reactjs state

我正在尝试修改状态并采用新状态进行渲染。
当我单击并修改(将{isClicked: true}添加到数组)时,onClicked函数中的console.log(this.state.listOfQuotes)返回修改后的状态的完整数组(我要使用)
但是渲染后,console.log(this.state.listOfQuotes)仅返回一个单击的元素,甚至没有修改一个......

任何帮助/提示,​​不胜感激!

这是我的代码

import React from "react";

export class Quotes extends React.Component {
  constructor(props) {
    super(props);
    this.state = { listOfQuotes: [] };
    this.vote = this.vote.bind(this);
    this.onClicked = this.onClicked.bind(this);
  }
  componentDidMount() {
    const url = "https://programming-quotes-api.herokuapp.com/quotes";
    fetch(url)
      .then(res => res.json())
      .then(quote => {
        this.setState({
          listOfQuotes: quote
        });
      });
  }
  onClicked(id) {
    const quotes = [...this.state.listOfQuotes];
    const clickedQuote = quotes.findIndex(quote => quote.id === id);
    console.log("onclicked", clickedQuote);
    const newArray = { ...quotes[clickedQuote], isClicked: true };
    console.log(newArray);
    this.setState(prevState => ({
      listOfQuotes: [
        ...prevState.listOfQuotes.splice(clickedQuote, 1, newArray)
      ]
    }));
    console.log(this.state.listOfQuotes);  ----------> this one returns what i want 
  }
  render() {
    console.log(this.state.listOfQuotes); -----------> i want to have same result as above state
    return (
      <div className="quotes">
        <div>
          {this.state.listOfQuotes.map((quote, idx) => (
            <div key={idx}>
              <div onClick={() => this.onClicked(quote.id)}>
                {!quote.isClicked ? (
                  <div className="before-clicked">{quote.en}</div>
                ) : (
                  <div className="after-clicked">{quote.en}</div>
                )}
              </div>
              <div>By {quote.author}</div>
              <div>Rating {quote.rating}</div>
              <div className="vote">
                <span>{quote.numberOfVotes}</span>
              </div>
            </div>
          ))}
        </div>
      </div>
    );
  }
}

1 个答案:

答案 0 :(得分:1)

onClicked方法存在问题。

它没有正确修改阵列。

我认为这是可以做到的。

 onClicked(id) {
    let quotes = [...this.state.listOfQuotes];

    const clickedQuoteIndex = quotes.findIndex(quote => quote.id === id);

    // Modify the object on the found index and assign true to "isClicked"
    quotes[clickedQuoteIndex].isClicked = true;

    // And then setState with the modified array
    // Since setState is async, so the console shouldn't be called immediately 
    // but rather in the callback
    this.setState({ listOfQuotes: quotes }, () => {
        console.log(this.state.listOfQuotes);
    });
}