Как получить случайный объект из списка, находящийся в state React

Рейтинг: 0Ответов: 1Опубликовано: 13.08.2023

Есть код:

import {Component} from "https://cdn.skypack.dev/react@17.0.1";
import ReactDOM from "https://cdn.skypack.dev/react-dom@17.0.1"
import React from 'https://esm.sh/react@18.2.0'

class App extends React.Component{
  constructor(props){
    super(props);
    this.state = {
      quote: [
        {
          text: 'dfsdf',
          author: 'sdf'
        },
        {
          text: 'dfsdfdf',
          author: 'kjhgfv'
        },
      ],
      random_q: null,
    }
    
    this.getRandomElement = this.getRandomElement.bind(this)
  }
  
  getRandomElement(){
    const text = document.getElementById('text')
    const author = document.getElementById('author')
    
    this.setState({
        random_q: this.state.quote[Math.floor(Math.random() * 
  this.state.quote.length)]
      })
    
    text.innetHTML = this.state.random_q.text
    author.innetHTML = this.state.random_q.author
  }
  
  render(){
    return (
      <>
        <div id="text">{this.state.quote[Math.floor(Math.random() * 
  this.state.quote.length)].text}</div>
        <div id="author">{this.state.quote[Math.floor(Math.random() * 
  this.state.quote.length)].author}</div>
        <div id="new-quote"><button onClick = {this.getRandomElement}>New quote</button></div>
        <a id="tweet-quote"></a>
      </>
    )
  }
}

ReactDOM.render(<App />, document.getElementById('quote-box'));
#quote-box{
  margin-left: 55px
}
<div id="quote-box">
  
</div>

Он получает случайную цитату и её автора из state, но почему-то цитата и авторы разные, но должно быть те же авторы, что и у цитаты в state, а не случайные. Как это можно исправить?

Ответы

▲ 0

Вы при каждом рендере для каждого из значений получали случайное число, поэтому и получали разные тексты и авторов.

Так же в вашей функции вы обращались к элементам DOM, в обход реакта, что не правильно и может привести ошибкам.

Надо убрать из функции обращение к DOM дереву и вставку данных в элементы, оставить только сохранение состояния компонента и в рендере добавить условие на отображение(если this.state.ramdom_q заполнен, отображаем)

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      quote: [
        {
          text: "text2",
          author: "avtor1"
        },
        {
          text: "text2",
          author: "avtor2"
        },
      ],
      random_q: null
    };

    this.getRandomElement = this.getRandomElement.bind(this);
  }

  getRandomElement() {
    this.setState({
      random_q: this.state.quote[
        Math.floor(Math.random() * this.state.quote.length)
      ]
    });
  }

  render() {
    return (
      <>
        {this.state.random_q && <>
          <div>{this.state.random_q.text}</div>
          <div>{this.state.random_q.author}</div>
        </>}
        <div id="new-quote">
          <button onClick={this.getRandomElement}>New quote</button>
        </div>
      </>
    );
  }
}