React 使用状态转换

React useState conversion

我制作了一个静态网页应用程序,我一直在慢慢将其转换为 React(MERN 堆栈)以使其更加dynamic/so我将不必配置每个 HTML 文档。这是一个使用 Google 模型查看器的产品配置器。

我对使用全栈工作流程还很陌生,但到目前为止我发现它非常有趣!然而,我在理解如何将我的一些普通 JS 转换为在 React 中工作时遇到了麻烦。当用户单击按钮时,此特定脚本将更改 source/3D 模型。下面是我目前在静态网页上工作的代码片段。

import {useEffect, useState} from "react";
import {useSelector, useDispatch} from "react-redux";

// Actions
import {getProductDetails} from "../redux/actions/productActions";

const ProductScreen = ({match}) => {

    const dispatch = useDispatch();

    const [currentSrc, setCurrentSrc] = useState()
    const [srcOptions, setSrcOptions] = useState()


    const productDetails = useSelector((state) => state.getProductDetails);
    const {loading, error, product} = productDetails;


    useEffect(() => {
      if (product && match.params.id !== product._id) {
        dispatch(getProductDetails(match.params.id));
        setCurrentSrc(product.src);
        setSrcOptions(product.srcList);
      }
    }, [dispatch, match, product]);
return (
<div className="productcreen">
  {loading ? (
  <h2> Loading...</h2>) : error ? (
  <h2>{error}</h2>) : (
  <>
    <div className='sizebuttons'>
    {srcOptions.map((src) => (
        <button onClick={() => setCurrentSrc(src)}>{src}{product.size}</button>
    ))}
    {srcOptions.map((src) => (
        <button onClick={() => setCurrentSrc(src)}>{src2}{product.size2}</button>
    ))}
    {srcOptions.map((src) => (
        <button onClick={() => setCurrentSrc(src)}>{src3}{product.size3}</button>
    ))}
    </div>
    <div className="productscreen__right">
      <model-viewer id="model-viewer" src={currentSrc} alt={product.name} ar ar-modes="scene-viewer quick-look" ar-placement="floor" shadow-intensity="1" camera-controls min-camera-orbit={product.mincameraorbit} max-camera-orbit={product.maxcameraorbit} interaction-prompt="none">
        <button slot="ar-button" className="ar-button">
                    View in your space
                  </button>
      </model-viewer>
    </div>
    </> )} )};

数据库如下所示:

“product.size”正在从 MongoDB 拉入,我想知道我是否可以将模型与:“product.src”、“[=40=”交换]2","product.src3" (也已在数据库中定义)我假设我需要使用 useState 来切换源,但我不确定。任何帮助将不胜感激!如果您想查看我正在尝试完成的静态网页,您可以查看它 here 如果有帮助的话。

以下是产品在 redux 中的导出方式:

import * as actionTypes from '../constants/productConstants';
import axios from 'axios';

export const getProductDetails = (id) => async(dispatch) => {
  try {dispatch({type: actionTypes.GET_PRODUCT_DETAILS_REQUEST});

    const {data} = await axios.get(`/api/products/${id}`);

    dispatch({
      type: actionTypes.GET_PRODUCT_DETAILS_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: actionTypes.GET_PRODUCT_DETAILS_FAIL,
      payload: error.response && error.response.data.message ?
        error.response.data.message :
        error.message,
    });
  }
};

您可以使用 React 中的 useState 钩子来创建状态。从数据库中获取产品后,您可以使用 setCurrentSrc 设置初始值,或者如果它来自道具,您可以像这样设置初始值:const [currentSrc, setCurrentSrc] = useState(props.product.src).

然后更改模型查看器的 src 以使用状态值,以便在状态值更改时自动重新呈现。最后,使用 setCurrentSrc 函数将 onClick 处理程序添加到某些按钮以更改状态。

const ProductViewer = (props) => {
  const [currentSrc, setCurrentSrc] = useState()
  const [srcOptions, setSrcOptions] = useState()

  const dispatch = useDispatch()
  const { loading, error, product } = useSelector(
    (state) => state.getProductDetails
  )
  useEffect(() => {
    if (product && match.params.id !== product._id) {
      dispatch(getProductDetails(match.params.id))
    }
  }, [dispatch, match, product])

  // update src and srcOptions when product changes
  useEffect(() => {
    setCurrentSrc(product.src)
    setSrcOptions(product.srcList)
  }, [product])

  return (
    <div className="productscreen__right">
      <model-viewer
        id="model-viewer"
        src={currentSrc}
        alt={product.name}
        ar
        ar-modes="scene-viewer quick-look"
        ar-placement="floor"
        shadow-intensity="1"
        camera-controls
        min-camera-orbit={product.mincameraorbit}
        max-camera-orbit={product.maxcameraorbit}
        interaction-prompt="none"
      >
        <button slot="ar-button" className="ar-button">
          View in your space
        </button>

        {/* add your switch buttons somewhere... */}
        {/* this assumes you have a srcList, but this could also be hardcoded */}
        {srcOptions.map((src) => (
          <buttton onClick={() => setCurrentSrc(src)}>{src}</buttton>
        ))}
      </model-viewer>
    </div>
  )
}