【问题标题】:Redirect with state values in react在反应中使用状态值重定向
【发布时间】:2021-11-16 22:30:23
【问题描述】:

大家好。

我有一个使用 react 和 react-redux 的第二手市场。 在主页面,您可以选择您想查看的产品类别。

import { Fragment, useEffect, useState } from "react";
import { useSelector, useDispatch } from "react-redux";
import { obtenerProductosAction } from "../actions/productoActions";
import Producto from "./Producto";
import PaginasBtn from "./PaginasBtn";

const Productos = (props) => {

  //const {busqueda} = (props.location && props.location.state)
  const productos = useSelector((state) => state.productos.productos);
  const paginasTotales = useSelector((state) => state.productos.paginas);
  const paginas = new Array(paginasTotales).fill(null).map((v, i) => i);

  const [busqueda, setBusqueda] = useState('all'); //SELECCION DE CATEGORIA DE PRODUCTOS A MOSTRAR  
  
  const [pageNumber, setPageNumber] = useState();

  //PARA PODER RECIBIR DEL COMPONENTE PAGINASBTN LOS VALORES DE LOS NUM Y EL CAMBIO (ES EL CHILD)
  const envioPagina = (pagina) => {
    console.log(pagina);
    setPageNumber(pagina);
  };

  const dispatch = useDispatch();

  const cargarProductos = (busqueda, pageNumber) =>
    dispatch(obtenerProductosAction(busqueda, pageNumber));
  //  const busquedaStore = window.localStorage.getItem('valorBusqueda')
  
  useEffect(() => {        
   
    cargarProductos(busqueda, pageNumber);
    console.log("vuelvo a llar a la api");
    // eslint-disable-next-line
  }, [busqueda, pageNumber ]);

  console.log(pageNumber);
  
  return (
    <Fragment>
      <div
        className="container-fluid  my-2 p-1 mt-4"
        style={{ position: "relative" }}
      >
        <div>
          {/* <h2 className="text-center">ENCUENTRA LO QUE ESTÁS BUSCANDO</h2> */}
          <div className=" mb-3 col-6 mx-auto">
            <form>
              <div className="container d-flex ">
                <select
                  className="form-select col-6"
                  defaultValue={busqueda}
                  name="categoria"
                  //value={busqueda}
                  onChange={(e) => setBusqueda(e.target.value)}
                >
                  {/* <option value="" selected>
                  Selecciona el tipo de producto
                </option> */}
                <option value="">Selecciona los productos</option>
                  <option value="all">Ver Últimos los Productos</option>
                  <option value="tabla">Tabla</option>
                  <option value="vela">Vela</option>
                  <option value="botavara">Botavara</option>
                  <option value="mastil">Mastil</option>
                  <option value="accesorio">Accesorio</option>
                </select>
                {/* <button className="btn btn-outline-primary text-center ms-2">
                  Buscar
                </button> */}
              </div>
            </form>
            <div>
              <h2 className="mt-5 text-center">Categoria: {busqueda}</h2>
            </div>
            {/* <label className="mb-2">Selecciona el tipo de producto</label> */}
          </div>
        </div>
        <div className=" row row-cols-2 row-cols-xs-2 row-cols-sm-2 row-cols-lg-4 g-3 ">
          {productos === undefined
            ? null
            : productos.map((producto, busqueda) => (
                <Producto key={producto._id} producto={producto} busqueda={busqueda}/>
              ))}
        </div>
        <div className="d-flex justify-content-center mt-4 ">
          {paginas.map((pagina) => (
            <PaginasBtn
              key={pagina}
              paginaS={pagina}
              envioPagina={envioPagina}
            />
            
          ))}
        </div>
      </div>
    </Fragment>
  );
};

export default Productos;

这会从 API 加载产品和分页。

然后我可以单独查看产品:

Product.js 组件:

import { Fragment } from "react";
import "./Producto.css";
//import './ProductoUser.css'
import { useHistory } from "react-router-dom";
//import { useSelector } from "react-redux";
//REDUX
import { useDispatch } from "react-redux";
import { obtenerProductoIdAction } from "../actions/productoActions";
//import { obtenerProductoVisionar } from "../actions/productoActions";

const Producto = ({ producto }) => {
  //LOD PRODUCTOS LLEGAN POR PROPS DE PRODUCTOS.JS
  //const { user: currentUser } = useSelector((state) => state.auth);
  //console.log(producto._id)
  const { title, price, images } = producto;
  const dispatch = useDispatch();
  const history = useHistory();

  // console.log(currentUser)

  const verProductoId = (producto ) => {
    dispatch(obtenerProductoIdAction(producto));
    console.log(producto);

    history.push(`/productos/${producto._id}`);
  };

  return (
    <Fragment>
      <div className="col">
        <div className="card shadow-sm gap-2  me-0">
          <div className="">
            <img
              src={images[0].url}
              className="card-img-top"
              alt={images[0].filename}
            ></img>
          </div>
          <div className="card-body text-center">
            <h5 className="price-hp">{price}€</h5>
            <h5 className="titleH5 card-title text-center">{title}</h5>
            <button
              className="btn btn-outline-primary mt-2 mb-1" 
              onClick={() => verProductoId(producto) }
            >
              Ver Producto
            </button>
          </div>
        </div>
      </div>
      {/* <div className="col-sm-6 col-md-3 col-lg-3 col-xl-2">
      <div className="card mb-2 ">
        <div className="card-header text-center">
          <h5 className='display-7'>{title}</h5>
        </div>        
        <img
            className="image-fluid m-3"
            style={{ height: '100px', objectFit: 'cover'}}
            src={images[0].url}
            alt="imagen nula"
          ></img>
        <div className="card-body text-center bg-light">
          <p style={{ color: "red" }}>Precio: {price}€</p>
          <button
            className="btn btn-primary"
            onClick={() => verProductoId(producto)}
          >
            Ver Producto
          </button>
        </div>
        </div>
      </div> */}
    </Fragment>
  );
};

export default Producto;

在看到完整的产品后, VerProducto.js:

import { Fragment } from "react";
import { useSelector } from "react-redux";
import { Link,  Redirect, useLocation, useHistory} from "react-router-dom";
import "./VerProducto.css";

const VerProducto = () => {
 
  const location = useLocation()
  const history = useHistory();
  
  const producto = useSelector((state) => state.productos.productoId);
  console.log(producto);

  if (!producto) {
    return null;
  }
  const { title, price, description, images, contacto } = producto;
  
  
  return (
    <Fragment>
      <div className="col">
        <div className="card1 h-100 mt-5">
          <a href={images[0].url} target="_blank" rel="noreferrer">
            <img
              src={images[0].url}
              className="card-img-top1 mt-3"
              alt={images[0].filename}
            ></img>
          </a>
          <div className="card-body">
            <div className="clearfix mb-3 text-center">
              <span className=" price-hp1">Precio: {price} €</span>
            </div>
            <h5 className="card-title titleH5V rounded text-center">{title}</h5>
            <div className="card-header mb-2">
              <span className="card-title pproducto text-center">Descripción:</span>
              <p className="card-title pproducto">{description}</p>
            </div>
            <div className="card-header">
              <span className="card-title  pproducto text-center">Contacto:</span>
              <p className="card-title pproducto ">{contacto}</p>
            </div>
            <button className= 'btn btn-info' onClick={(e)=>history.push({pathname:'/productos', state: {busqueda: 'vela'}})}>Volver a productos</button>

             <div className="text-center my-4">
              <Link to={{pathname: '/productos/'}} className="btn btn btn-info">
                VOLVER A PRODUCTOS
              </Link>
            </div> 
          </div>
        </div>
      </div>
      
    </Fragment>
  );
};

export default VerProducto;

当我使用其中一个选项(链接或历史记录)时,我会尝试返回到我之前所在的同一页面并在同一类别中。 (我想我什么时候会在第 (55) 页并希望返回同一页面以查看其他完整产品。

但是应用程序返回到主页面并返回到默认类别....

有人可以给我亮灯继续....谢谢!!!

【问题讨论】:

  • 如何在全局状态(redux)上设置过滤器并在用户加载页面时获取它?另一种选择是在设置过滤器和页面的 url 上传递一些查询参数,由您决定
  • 比@barden,也许我在你的反应中处于低水平,因为我知道如何传递查询参数,但我如何传递给 useState 以显示上一页和过滤器。 ...?谢谢。

标签: reactjs redux


【解决方案1】:

感谢您的想法@barden, 现在我可以在代码中进行这些更新了。

Productos.js(组件)

import { Fragment, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { Link, useLocation } from "react-router-dom";
import {
  obtenerProductosAction,
  obtenerCategoriaActions,
  obtenerPaginaAction,
} from "../actions/productoActions";
import Producto from "./Producto";
import "./Producto.css";

const Productos = () => {
  const location = useLocation();
  console.log(location);

  const productos = useSelector((state) => state.productos.productos);
  const paginasTotales = useSelector((state) => state.productos.paginas);  
  const errores = useSelector((state)=> state.productos.error401)
  console.log(errores)

  const paginas = new Array(paginasTotales).fill(null).map((v, i) => i);  

  const params = new URL(document.location).searchParams;
  let busquedaquery = params.get("busqueda");
  let pagequery = params.get("page");

  const dispatch = useDispatch();

  const cargarProductos = () =>
    dispatch(obtenerProductosAction(busquedaquery, pagequery));

  const cargarCategoria = () =>
    dispatch(obtenerCategoriaActions(busquedaquery));

  useEffect(() => {    
    cargarCategoria(busquedaquery);
    cargarProductos(busquedaquery, pagequery);
    dispatch(obtenerPaginaAction(pagequery));
    console.log("vuelvo a llar a la api");
    // eslint-disable-next-line
  }, [busquedaquery, pagequery]);

  return (
    <Fragment>

      {errores ?        
        <h2 className='col-6 alert alert-warning mx-auto mt-5 text-center'>Inicia Sesión o Registrate</h2>: null}
      <div
        className="container-fluid  my-2 p-1 mt-4"
        style={{ position: "relative" }}
      >
        <div>          
          <div className=" mb-3 col-6 mx-auto">
            <form>
              <div className="container d-flex ">
                <select
                  className="form-select col-6"
                  defaultValue={busquedaquery}
                  name="busqueda"
                  //value={busqueda}
                  onChange={(e) => e.target.value} //SELECCION DE CATEGORIA DE PRODUCTOS A MOSTRAR
                >
                  <option value="all">Ver Últimos los Productos</option>
                  <option value="tabla">Tabla</option>
                  <option value="vela">Vela</option>
                  <option value="botavara">Botavara</option>
                  <option value="mastil">Mastil</option>
                  <option value="accesorio">Accesorio</option>
                </select>
                <button className="btn btn-outline-primary ms-3">Buscar</button>
              </div>
            </form>
            <div>
              <h2 className="mt-5 text-center">Categoria: {busquedaquery}</h2>
            </div>
            
          </div>
        </div>
        <div className="row row-cols-2 row-cols-xs-2 row-cols-sm-2 row-cols-lg-4 g-3 justify-content-center ">
          {productos === undefined
            ? null
            : productos.map((producto, busqueda) => (
                <Producto
                  key={producto._id}
                  producto={producto}
                  busqueda={busqueda}
                />
              ))}
        </div>
        <div className="d-flex justify-content-center mt-4 ">
          {paginas.map((pagina) => (
            <Link
              type="submit"
              key={pagina}
              to={`/productos?busqueda=${busquedaquery}&page=${pagina}`}
              className="rounded btn btn-select page-link"
            >
              {pagina + 1}
            </Link>
          ))}
        </div>
      </div>
    </Fragment>
  );
};

export default Productos;

我现在将搜索和带有 redux 的页面保存在全局状态,然后使用 reducer,我可以在页面中调用我希望类别状态和页面准确返回到该页面和该类别的页面。

VerProducto.js(组件)

import { Fragment } from "react";
import { useSelector } from "react-redux";
import { Link} from "react-router-dom";
import "./VerProducto.css";

const VerProducto = () => {    
 
  
  const producto = useSelector((state) => state.productos.productoId);
  const busqueda = useSelector((state) => state.productos.categoria)
  const paginaActual = useSelector((state)=> state.productos.paginaActual)
  console.log(busqueda, paginaActual);

  if (!producto) {
    return null;
  }
  const { title, price, description, images, contacto } = producto;
  
  
  return (
    <Fragment>
      <div className="col">
        <div className="card1 h-100 mt-5">
          <a href={images[0].url} target="_blank" rel="noreferrer">
            <img
              src={images[0].url}
              className="card-img-top1 mt-3"
              alt={images[0].filename}
            ></img>
          </a>
          <div className="card-body">
            <div className="clearfix mb-3 text-center">
              <span className=" price-hp1">Precio: {price} €</span>
            </div>
            <h5 className="card-title titleH5V rounded text-center">{title}</h5>
            <div className="card-header mb-2">
              <span className="card-title pproducto text-center">Descripción:</span>
              <p className="card-title pproducto">{description}</p>
            </div>
            <div className="card-header">
              <span className="card-title  pproducto text-center">Contacto:</span>
              <p className="card-title pproducto ">{contacto}</p>
            </div>
            
            <div className="text-center my-4">
              <Link to={`/productos?busqueda=${busqueda}&page=${paginaActual}`} className="btn btn-outline-success">
                VOLVER A PRODUCTOS
              </Link>
            </div>
          </div>
        </div>
      </div>
      
    </Fragment>
  );
};

export default VerProducto;

如果有人想查看完整代码,这里是 git 的链接: https://github.com/ddaudiosolutions/2nHandMarket-Usuario

【讨论】:

    猜你喜欢
    • 2020-04-22
    • 2019-12-31
    • 2021-12-28
    • 1970-01-01
    • 2020-11-28
    • 2020-03-23
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多