Как выполнить мутацию статуса выпадающих списков в ReactJS?

Я хочу изменить состояние, когда элемент выбран в моем раскрывающемся списке, но возникает ошибка, которая не меняется без повторного нажатия.

Я знаю, что есть связанные вопросы, но мой код - это частный случай.

Как выполнить мутацию статуса выпадающих списков в ReactJS?

То же самое происходит со мной, как это изображение с двумя раскрывающимися списками.

Как выполнить мутацию статуса выпадающих списков в ReactJS?

Меняю "Mes" но не работает пока не вернешься и не выберешь другое значение. Там я просто перешел на "месяц 4".

Как выполнить мутацию статуса выпадающих списков в ReactJS?

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import format from 'date-fns/format';
import gql from 'graphql-tag';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';

import { Link } from 'react-router-dom';

import { graphql } from 'react-apollo';

import '../../../node_modules/bootstrap/dist/css/bootstrap.css';
import './style.css';

import {
  ButtonDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
} from 'reactstrap';
import axios from 'axios';
import TituloSmall, { types } from '../TituloSmall';

const query0 = gql`
  query postsDiaComoHoy($dia: Int!, $mes: Int!) {
    posts(first: 2, dia: $dia, mes: $mes, categoria: 28) {
      rows {
        id
        fecha_dia_hoy
        imagen_intro
        titulo
        introtext
        autor
        fulltext
        fulltext2
        imagen_banner
        categoria {
          id
        }
        tags {
          id
          titulo
        }
      }
      count
    }
  }
`;

const renderTagItem = item => {
  const { id, titulo } = item;
  return (
    <Link key = {id} to = {`/tags/${id}/`}>
      <div className = "tag">{titulo}</div>
    </Link>
  );
};

const removeTagHtml = valor => valor.replace(/(<([^>]+)>)/g, '');
const removerTwitter = valor => valor.replace(/- @\w+/g, '');

let updated = 0;

let dates = format(Date(), 'D');
let month = format(Date(), 'M');
export class DayScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      data: this.props,
      currentIndex: 0,
      sortItem1: month,
      sortItem2: dates,
      cantidadMeses: [
        'Enero',
        'Febrero',
        'Marzo',
        'Abril',
        'Mayo',
        'Junio',
        'Julio',
        'Agosto',
        'Septiembre',
        'Octubre',
        'Noviembre',
        'Diciembre',
      ],
      diasMes: [
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16,
        17,
        18,
        19,
        20,
        21,
        22,
        23,
        24,
        25,
        26,
        27,
        28,
        29,
        30,
        31,
      ],
    };
  }

  state = {
    items: [],
  };

  componentDidUpdate() {
    this.getArticles();
    updated = 0;
  }



  getArticles = async () => {
    const changeArticles = `
    {
      posts(first: 3, dia: ${this.state.sortItem2}, mes: ${month}) {
        rows {
          id
          fecha_dia_hoy
          imagen_intro
          titulo
          introtext
          autor
          views
          fulltext
          fulltext2
          imagen_banner
            categoria {
            id
          }
          tags{
            id
            titulo
          }
          }
        count
      }
    }
    `;

    if (updated) {
      try {
        const response = await axios.get(
          `http://localhost:4000/graphql/?query=${changeArticles}`,
        ) .then(response => {
          this.setState(() => ({
            items: response.data.data.posts.rows,
          }));

          let { data } = this.props;
          const { items } = this.state;

          data.posts.rows = items;

          return response;
        });

        // Log the response so we can look at it in the console

        // Set the data to the state



      } catch (error) {
        // If there's an error, set the error to the state
        // this.setState(() => ({ error }));
        console.info(error);
        // console.info(this.state.error);
      }
    }
  };

  selectIndex = direction => {
    const { currentIndex } = this.state;
    const {
      data: {
        posts: { count },
      },
    } = this.props;

    let nexIndex = currentIndex + direction;
    nexIndex = nexIndex < 0 ? count - 1 : nexIndex;
    nexIndex = nexIndex >= count ? 0 : nexIndex;
    this.setState({ currentIndex: nexIndex });
  };

  monthSelected() {
    const { sortItem1, sortItem2, dropdownOpen1 } = this.state;
    this.setState({
      dropdownOpen1: !dropdownOpen1, 
    });
    if (dropdownOpen1) {
      month = sortItem1;
      dates = sortItem2;
      updated = 1;
    }
  }

  dateSelected() {
    const { sortItem1, sortItem2, dropdownOpen2 } = this.state;

    this.setState({
      dropdownOpen2: !dropdownOpen2,
    });
    if (dropdownOpen2) {
      month = sortItem1;
      dates = sortItem2;
      updated = 1;
    }
  }


  onDiasChanged=(e)=>{
     this.setState({sortItem2:[...e.currentTarget.innerHTML]});
   }

   onMesChanged=(e)=>{
    this.setState({sortItem1:[...e.currentTarget.innerHTML]});
  }



  render() {
    const { data } = this.props;
    if (data.loading) {
      return <div>Loading...</div>;
    }
    if (data.error) {
      return <div>{data.error.message}</div>;
    }

    if (data.posts.rows.length <= 0) {
      return <div>Nada que mostrar...</div>;
    }
    const {
      data: {
        posts: { rows },
      },
    } = this.props;

    this.items = this.props.data.posts.rows;
    const {
      currentIndex,
      sortItem1,
      cantidadMeses,
      sortItem2,
      dropdownOpen1,
      dropdownOpen2,
      diasMes,
    } = this.state;

    const item = rows[currentIndex] ? rows[currentIndex] : rows[0];

    const html = item.fulltext + item.fulltext2;
    const image = `${process.env.REACT_APP_IMG_BASE}${item.imagen_intro ||
      item.imagen_banner}`;

    data.variables.mes = sortItem1;
    data.variables.dia = sortItem2;
    return (
      <div className = "containerDiaComoHoyNoticia">
        <div className = "box">
          <span />
          <span />
          <div className = "mesTexto">{cantidadMeses[sortItem1 - 1]}</div>
          <div className = "diaTexto">{sortItem2}</div>
        </div>
        <div>
          <div className = "textoContainer">
            <div className = "tituloDiaComoHoyNoticia">
              {'BUSCA QUE OCURRIÓ EL DÍA QUE TU QUIERAS EN EL FÚTBOL'}
            </div>
            <div className = "separatorLinea" />
            <div className = "listaMesDia">
              <span className = "circuloMesDia">1</span>
              <span>Mes</span>
              <ButtonDropdown
                isOpen = {dropdownOpen1}
                toggle = {() => {
                  this.monthSelected();
                }}>
                <DropdownToggle color = "white" caret>
                  {sortItem1}
                </DropdownToggle>
                <DropdownMenu>
                  {cantidadMeses.map((items, i) => (
                    <DropdownItem
                      dropDownValue = "Mes"
                      dropDownValue = "Mes" onClick = {this.onMesChanged}>
                      {i + 1}
                    </DropdownItem>
                  ))}
                </DropdownMenu>
              </ButtonDropdown>
              <span className = "circuloMesDia">2</span>
              <span>Dia</span>

              <ButtonDropdown
                isOpen = {dropdownOpen2}
                toggle = {() => {
                  this.dateSelected();
                }}>
                <DropdownToggle caret>{sortItem2}</DropdownToggle>
                <DropdownMenu>
                  {diasMes.map(i => (
                    <DropdownItem
                      dropDownValue = "Mes" onClick = {this.onDiasChanged}>
                      {i}
                    </DropdownItem>
                  ))}
                </DropdownMenu>
              </ButtonDropdown>
            </div>
          </div>
        </div>
        {rows.map(itemArticulo => (
          <div className = "listaNoticiasContenido">
            <img
              alt = {itemArticulo.titulo}
              src = {process.env.REACT_APP_IMG_BASE + itemArticulo.imagen_intro}
              className = "listaNoticiasImagen"
            />
            <div className = "rectanguloIconoPlay" />
            <div className = "contenidoArticulo">
              <div className = "tituloArticulo"><a href = "#" onClick = {this.state.currentIndex = 1}>{itemArticulo.titulo}</a></div>
              <div className = "descripcionArticulo">
                {removeTagHtml(itemArticulo.introtext)}
              </div>
              <div className = "escritor">
                <div className = "nombreAutor">
                  <div>
                    <FontAwesomeIcon icon = "user-circle" />
                    <span className = "autorArticulo">
                      {removerTwitter(itemArticulo.autor) || 'Sin autor'}
                    </span>
                    <FontAwesomeIcon icon = "eye" />
                    <span className = "vistasTotalesArticulos">
                      {itemArticulo.views}
                    </span>
                    <FontAwesomeIcon icon = "calendar" />
                    <span className = "cantidadArticulosEscritos">
                      {itemArticulo.fecha_dia_hoy}
                    </span>
                  </div>
                </div>
              </div>
            </div>
            <div className = "separadorArticulos" />
          </div>
        ))}
        <h2 className = "tituloDescripcion">{item.titulo}</h2>
        <div className = "titlesContainer">
          <TituloSmall
            iconName = "user-circle"
            label = {item.autor || 'Sin autor'}
          />
          <TituloSmall
            iconName = "calendar"
            label = {format(item.fecha_dia_hoy, 'DD/MM/YYYY')}
          />
        </div>

        <div className = "imageIntro">
          <img className = "imageDescription" src = {image} alt = {item.titulo} />
          <div className = "esquinaFigura">
            <div className = "boxWhite">
              <span />
              <span />
              <div className = "mesTextoBoxWhite">
                {cantidadMeses[sortItem1 - 1]}
              </div>
              <div className = "diaTextoBoxWhite">{sortItem2}</div>
            </div>
          </div>
        </div>

        <article dangerouslySetInnerHTML = {{ __html: html }} />
        <TituloSmall iconName = "tags" label = "Tags" type = {types.BIG} />
        {item.tags.map(itemsTags => renderTagItem(itemsTags))}
      </div>
    );
  }
}

DayScreen.propTypes = {
  data: PropTypes.shape({
    loading: PropTypes.bool.isRequired,
    currentSortItem: PropTypes.string.isRequired,
    error: PropTypes.shape({ message: PropTypes.string }),
  }).isRequired,
};

DayScreen.defaultProps = {};

const queryOptions = {
  options: () => ({
    variables: {
      dia: dates,
      mes: month,
    },
  }),
};

export default graphql(query0, queryOptions)(DayScreen);

Я хочу, чтобы изменение состояния происходило без нажатия двойного щелчка, и происходила задержка, которую я показал на изображении.

Спасибо за вашу помощь!

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
0
0
253
2

Ответы 2

Первая ошибка, которую я вижу, заключается в том, что вы не можете установить состояние напрямую как this.state.sortItem = e.target.innerHTMLВместо этого вы должны использовать this.setState({ sortItem: e.targetinnerHTML })

Y por пользу, намерение не использовать испанский язык xD эс уна мала práctica.

Вы имеете в виду, что это будет что-то вроде этого? onClick = {e => {                         this.stateState ({sortItem1: e.target.innerHTML});                       }}>                       {i + 1}

Mangux 14.02.2019 09:15

да. И я бы также обернул его в функцию для лучшей читабельности

Rudy 14.02.2019 09:43

Я выдаю ошибку: TypeError: _this4.stateState не является функцией

Mangux 14.02.2019 09:50

Готово, но ничего не делать сейчас, когда я нажимаю

Mangux 14.02.2019 09:55

Вы напрямую изменили state и не установили состояние с помощью метода setState, поэтому ваш метод render не будет вызываться во время выбора, и из-за этого вы не получите изменения сразу после вызова вашего метода рендеринга, вы получите эти изменения. так что ваша реализация раскрывающегося списка должна быть похожа.

  onMessChanged=(e)=>{
     this.setState({sortItem2:e.currentTarget.innerHTML});
    }

  <DropdownMenu>
                  {diasMes.map(i => (
                    <DropdownItem
                      dropDownValue = "Mes"
                      onClick = {this.onMessChanged}>
                      {i}
                    </DropdownItem>
                  ))}
                </DropdownMenu>

Поскольку здесь вы используете reactstrap, возможно, ваша цель события может быть другой, поэтому вам нужно использовать currentTarget

currentTarget относится к элементу, к которому непосредственно присоединен прослушиватель событий, в то время как target по-прежнему относится к конкретному элементу, по которому мы щелкнули.

Я выразил это так, как вы упомянули, но это по-прежнему представляет ту же проблему. Я поставил функцию над рендерингом и OnClick this..onMessChanged, но она не работает

Mangux 14.02.2019 10:08

Я отлаживаю и только что понял, что в запросе Axios он сохраняет предыдущий идентификатор. Например: getArticles = async () => {     const changeArticles = `     {       posts (first: 3, day: $ {date}, month: $ {month}) { ** даты ** равно 13 и ** месяц ** равно 2. Я должен передать выбранный день, но он не отправляется, как я могу это сделать?

Mangux 14.02.2019 10:49

@Mangux: сообщения (первые: 3, диам.: ${this.state.sortItem2}, мес.: ${месяц})

Dhaval Patel 14.02.2019 12:45

Я так выразился, и просто нажав, он отправляет мне следующее сообщение: TypeError: Can not read property 'fulltext' of undefined Странно то, что выпадающий список не отображается со значениями, просто по умолчанию, и когда я нажимаю кнопку , появляется ошибка

Mangux 14.02.2019 13:33

Я уже решил это, то есть проблема неопределенности больше не появляется, но она по-прежнему не меняет состояние, когда я меняю элемент, и мне нужно снова щелкнуть. Я обновил код, как сейчас, не могли бы вы просмотреть его, пожалуйста?

Mangux 14.02.2019 13:58

Другие вопросы по теме