如何更有效地利用道具?

时间:2019-02-11 03:05:43

标签: reactjs react-native graphql

我有一个代码,其中接收两个下拉列表的值,然后使用AXIOS的GET方法向我的graphql请求。我想知道我是否可以使用道具不做那种事情?我该怎么办?。

有两个下拉菜单,如果选择日期和月份,则应保留结果而不重新加载整个页面。

以下是有关其工作原理的图片:

选择日期和/或月份:

Sample image

结果和Axios的请求:

Sample image

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 Divider from '../Divider';
import TituloSmall, { types } from '../TituloSmall';
import Titulo from '../Titulo';
import '../../../node_modules/bootstrap/dist/css/bootstrap.css';
import './style.css';


import {
  ButtonDropdown,
  DropdownToggle,
  DropdownMenu,
  DropdownItem,
} from 'reactstrap';
import { addMonths } from 'date-fns';
import axios from 'axios';

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, '');

var updated = 0;
var dates = format(Date(), 'D'),
  month = format(Date(), 'M');
export class dayScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      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 = {
    error: null,
    items: [],
  };

  componentDidUpdate() {
    this.getAnime();
    this.render();
    updated = 0;
  }

  getAnime = async () => {
    const changeArticles = `
    {
      posts(first: 3, dia: ${dates}, 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,
        );

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

        // Set the data to the state
        this.setState(() => ({
          isLoaded: true,
          items: response.data.data.posts.rows,
        }));
        this.props.data.posts.rows = this.state.items;
      } catch (error) {
        // If there's an error, set the error to the state
        this.setState(() => ({ error }));
        console.log(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() {
    this.setState({
      dropdownOpen1: !this.state.dropdownOpen1,
    });
    if (this.state.dropdownOpen1) {
      this.props.data.variables.mes = this.state.sortItem1;
      this.props.data.variables.dia = this.state.sortItem2;
      month = this.state.sortItem1;
      dates = this.state.sortItem2;
      updated = 1;
    }
  }

  dateSelected() {
    this.setState({
      dropdownOpen2: !this.state.dropdownOpen2,
    });
    if (this.state.dropdownOpen2) {
      this.props.data.variables.mes = this.state.sortItem1;
      this.props.data.variables.dia = this.state.sortItem2;
      month = this.state.sortItem1;
      dates = this.state.sortItem2;
      updated = 1;
    }
  }

  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;

    const { currentIndex } = this.state;
    const item = rows[currentIndex];

    let html = item.fulltext + item.fulltext2;
    const description = item.introtext.replace(/(<([^>]+)>)/gi, '');
    const image = `${process.env.REACT_APP_IMG_BASE}${item.imagen_intro ||
      item.imagen_banner}`;

    return (
      <div className="containerDiaComoHoyNoticia">
        <div className="box">
          <span />
          <span />
          <div className="mesTexto">
            {this.state.cantidadMeses[this.state.sortItem1 - 1]}
          </div>
          <div className="diaTexto">{this.state.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>
            <div className="listaMesDia">
              <span className="circuloMesDia">1</span>
              <span>Mes</span>
              <ButtonDropdown
                isOpen={this.state.dropdownOpen1}
                toggle={() => {
                  this.monthSelected();
                }}>
                <DropdownToggle color="white" caret>
                  {this.state.sortItem1}
                </DropdownToggle>
                <DropdownMenu>
                  {this.state.cantidadMeses.map((items, i) => (
                    <DropdownItem
                      dropDownValue="Mes"
                      onClick={e => {
                        this.state.sortItem1 = e.target.innerHTML;
                      }}>
                      {i + 1}
                    </DropdownItem>
                  ))}
                </DropdownMenu>
              </ButtonDropdown>
              <span className="circuloMesDia">2</span>
              <span>Dia</span>

              <ButtonDropdown
                isOpen={this.state.dropdownOpen2}
                toggle={() => {
                  this.dateSelected();
                }}>
                <DropdownToggle caret>{this.state.sortItem2}</DropdownToggle>
                <DropdownMenu>
                  {this.state.diasMes.map(i => (
                    <DropdownItem
                      dropDownValue="Mes"
                      onClick={e => {
                        this.state.sortItem2 = e.target.innerHTML;
                      }}>
                      {i}
                    </DropdownItem>
                  ))}
                </DropdownMenu>
              </ButtonDropdown>
            </div>
          </div>
        </div>
        {rows.map((item, index) => (
          <div className="listaNoticiasContenido">
            <img
              alt={item.titulo}
              src={process.env.REACT_APP_IMG_BASE + item.imagen_intro}
              className="listaNoticiasImagen"
            />
            <div className="rectanguloIconoPlay"></div>
            <div className="contenidoArticulo">
              <div className="tituloArticulo">{item.titulo}</div>
              <div className="descripcionArticulo">
                {removeTagHtml(item.introtext)}
              </div>
              <div className="escritor">
                <div className="nombreAutor">
                  <div>
                    <FontAwesomeIcon icon="user-circle" />
                    <span className="autorArticulo">
                      {removerTwitter(item.autor) || 'Sin autor'}
                    </span>
                    <FontAwesomeIcon icon="eye" />
                    <span className="vistasTotalesArticulos">{item.views}</span>
                    <FontAwesomeIcon icon="calendar" />
                    <span className="cantidadArticulosEscritos">
                      {item.fecha_dia_hoy}
                    </span>
                  </div>
                </div>
              </div>
            </div>              <div className="separadorArticulos"></div>

          </div>
        ))}
        <h2 className="titulo">{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 class="esquinaFigura">
            <div className="boxWhite">
              <span />
              <span />
              <div className="mesTextoBoxWhite">
                {this.state.cantidadMeses[this.state.sortItem1 - 1]}
              </div>
              <div className="diaTextoBoxWhite">{this.state.sortItem2}</div>
            </div>
          </div>
        </div>

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

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

dayScreen.defaultProps = {};

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

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

没有Axios怎么办?与Axios一起使用时,这是否可扩展?有人告诉我道具是用来做这件事的,但我不知道该怎么做。

我想在没有Axios的情况下仅使用道具来做到这一点。接收下拉菜单的值,并使用graphql更改查询的页面部分。

1 个答案:

答案 0 :(得分:0)

您可以通过实现Apollo Client,从安装Apollo开始,然后按照文档在项目中进行设置来实现此目的。