简体   繁体   English

React 状态只返回一个元素

[英]React state returns only one element

I'm trying to modify state and take the new state to render.我正在尝试修改状态并采用新状态进行渲染。
When I click and modified(added {isClicked: true} to array), console.log(this.state.listOfQuotes) inside onClicked function returns modified the full array of state(which I want to use)当我单击并修改(将{isClicked: true}添加到数组)时,onClicked 函数内的console.log(this.state.listOfQuotes)返回修改后的完整状态数组(我想使用)
but after render, console.log(this.state.listOfQuotes) returns only one clicked element and not even modified one...但是在渲染之后, console.log(this.state.listOfQuotes)只返回一个点击过的元素,甚至没有修改过一个...

Any help/hint much appreciated!非常感谢任何帮助/提示!

Here is my code这是我的代码

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>
    );
  }
}

There is a problem with your onClicked method.您的 onClicked 方法有问题。

It is not modifying the array correctly.它没有正确修改数组。

In my opinion, this is how it could have done.在我看来,这就是它可以做到的。

 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);
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM