如何使用 MongoDB 在 React 中动态创建按钮数组?
How to dynamically create an array of buttons in React using MonogoDB?
我正在尝试使用 MERN 堆栈将我的静态产品配置器转换为动态产品配置器,我真的快要完成测试版本了!我一切正常,但我无法让它变得更加动态。在我的配置器中 here for example, I have the ability to change colors through a list of hard coded buttons that trigger an event. This gets tedious with the amount of products that I will be trying to deploy to our website, and some products are only available in one, two, or three materials. I have successfully uploaded an array to MongoDB and is structured like so:
所以我的主要问题是,我将如何生成嵌套在手风琴内部的按钮列表,就像我上面的示例一样,而手风琴的每个“部分”都有 material选择。
这是我对 HTML 的硬编码代码片段以及我目前拥有的一些功能:
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 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)
}, [dispatch, match, product]);
const changeColor = (event) => {
const modelViewer = document.querySelector("model-viewer");
modelViewer.variantName = event.target.value;
};
const [currentSrc, setCurrentSrc] = useState(product.src);
return (*/HTML/*)
}
<div className="accordion">
<div>
<input type="radio" name="accordion" id="Lacquer" className="accordion__input" />
<label htmlFor="Lacquer" className="materialLabel">Lacquer</label>
<div className="items">
<button onClick={changeColor} className='item' value='Ballet Pink'>Ballet Pink</button>
<button onClick={changeColor} className='item' value="Bellini Peach">Bellini Peach</button>
<button onClick={changeColor} className='item' value="Boeing Navy">Boeing Navy</button>
<button onClick={changeColor} className='item' value="Cessna Grey">Cessna Grey</button>
<button onClick={changeColor} className='item' value="Charter Coral">Charter Coral</button>
<button onClick={changeColor} className='item' value="Cirrus White">Cirrus White</button>
<button onClick={changeColor} className='item' value="Citation Blue">Citation Blue</button>
<button onClick={changeColor} className='item' value="Dash Pink">Dash Pink</button>
<button onClick={changeColor} className='item' value="Falcon Grey">Falcon Grey</button>
<button onClick={changeColor} className='item' value="Gulfstream Blue">Gulfstream Blue</button>
<button onClick={changeColor} className='item' value="Havilland Sage">Havilland Sage</button>
<button onClick={changeColor} className='item' value="Illuminating Yellow">Illuminating Yellow</button>
<button onClick={changeColor} className='item' value="Lear Green">Lear Green</button>
<button onClick={changeColor} className='item' value="Merlin Lavender">Merlin Lavender</button>
<button onClick={changeColor} className='item' value="Midnight Green">Midnight Green</button>
<button onClick={changeColor} className='item' value="Polar Ice">Polar Ice</button>
<button onClick={changeColor} className='item' value="Smoky Blue">Smoky Blue</button>
<button onClick={changeColor} className='item' value="Stratos Black">Stratos Black</button>
<button onClick={changeColor} className='item' value="Vitamin C">Vitamin C</button>
</div>
</div>
<div>
<input type="radio" name="accordion" id="Wood" className="accordion__input" />
<label htmlFor="Wood" className="materialLabel">Wood</label>
<div className="items">
<button onClick={changeColor} className='item' value="Golden Pecan Mappa Burl">Golden Pecan Mappa Burl</button>
<button onClick={changeColor} className='item' value="Golden Pecan Olive Ash">Golden Pecan Olive Ash</button>
<button onClick={changeColor} className='item' value="Natural Mappa Burl">Natural Mappa Burl</button>
<button onClick={changeColor} className='item' value="Natural Olive Ash">Natural Olive Ash</button>
<button onClick={changeColor} className='item' value="Provincial Mappa Burl">Provincial Mappa Burl</button>
<button onClick={changeColor} className='item' value="Provincial Olive Ash">Provincial Olive Ash</button>
</div>
</div>
</div>
现在我可以 console.log(product.material) 并查看产品 JSON,但我不确定如何提取该信息并将其插入
这是我用来获取 ProductDetails 的 redux/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,
});
}
};
如有任何帮助,我们将不胜感激!
为了简单起见,您应该创建一个自定义组件来表示您的输入收音机和循环
materials
对象列表
- 其中的值列表
在ProductScreen
中:
{
product && product.materials[0].map((material) => (
<CustomRadioButton material={material} changeColor={changeColor} />
));
}
创建一个新的 CustomRadioButton
组件
export const CustomRadioButton = ({ material, changeColor }) => {
const materialName = Object.keys(material);
if (!materialName) return <></>;
return (
<div>
<input
type='radio'
name='accordion'
id={materialName}
className='accordion__input'
/>
<label htmlFor={materialName} className='materialLabel'>
{materialName}
</label>
<div className='items'>
{material[materialName].map((item) => (
<button onClick={changeColor} className='item' value={item}>
{item}
</button>
))}
</div>
</div>
);
};
好的,在@LuccaPizzini 的帮助下,我终于弄清楚了如何让它发挥作用!
这是我必须做的:
在Product Screen
中:
{
product && (product.materials ||).map((material, index) => (
<CustomRadioButton key={index} material={material} changeColor={changeColor} />
))
}
创建一个新的 CustomRadioButton
组件:
export const CustomRadioButton = ({ material, changeColor }) => {
const materialName = Object.keys(material);
if (!materialName) return <></>;
return (
<div>
<input
type='radio'
name='accordion'
id={materialName}
className='accordion__input'
/>
<label htmlFor={materialName} className='materialLabel'>
{materialName}
</label>
<div className='items'>
{material[materialName].map((item) => (
<button key={item} onClick={changeColor} className='item' value={item}>
{item}
</button>
))}
</div>
</div>
);
};
本质上,这两个组件与他提供的内容相比变化很小。
我正在尝试使用 MERN 堆栈将我的静态产品配置器转换为动态产品配置器,我真的快要完成测试版本了!我一切正常,但我无法让它变得更加动态。在我的配置器中 here for example, I have the ability to change colors through a list of hard coded buttons that trigger an event. This gets tedious with the amount of products that I will be trying to deploy to our website, and some products are only available in one, two, or three materials. I have successfully uploaded an array to MongoDB and is structured like so:
所以我的主要问题是,我将如何生成嵌套在手风琴内部的按钮列表,就像我上面的示例一样,而手风琴的每个“部分”都有 material选择。
这是我对 HTML 的硬编码代码片段以及我目前拥有的一些功能:
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 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)
}, [dispatch, match, product]);
const changeColor = (event) => {
const modelViewer = document.querySelector("model-viewer");
modelViewer.variantName = event.target.value;
};
const [currentSrc, setCurrentSrc] = useState(product.src);
return (*/HTML/*)
}
<div className="accordion">
<div>
<input type="radio" name="accordion" id="Lacquer" className="accordion__input" />
<label htmlFor="Lacquer" className="materialLabel">Lacquer</label>
<div className="items">
<button onClick={changeColor} className='item' value='Ballet Pink'>Ballet Pink</button>
<button onClick={changeColor} className='item' value="Bellini Peach">Bellini Peach</button>
<button onClick={changeColor} className='item' value="Boeing Navy">Boeing Navy</button>
<button onClick={changeColor} className='item' value="Cessna Grey">Cessna Grey</button>
<button onClick={changeColor} className='item' value="Charter Coral">Charter Coral</button>
<button onClick={changeColor} className='item' value="Cirrus White">Cirrus White</button>
<button onClick={changeColor} className='item' value="Citation Blue">Citation Blue</button>
<button onClick={changeColor} className='item' value="Dash Pink">Dash Pink</button>
<button onClick={changeColor} className='item' value="Falcon Grey">Falcon Grey</button>
<button onClick={changeColor} className='item' value="Gulfstream Blue">Gulfstream Blue</button>
<button onClick={changeColor} className='item' value="Havilland Sage">Havilland Sage</button>
<button onClick={changeColor} className='item' value="Illuminating Yellow">Illuminating Yellow</button>
<button onClick={changeColor} className='item' value="Lear Green">Lear Green</button>
<button onClick={changeColor} className='item' value="Merlin Lavender">Merlin Lavender</button>
<button onClick={changeColor} className='item' value="Midnight Green">Midnight Green</button>
<button onClick={changeColor} className='item' value="Polar Ice">Polar Ice</button>
<button onClick={changeColor} className='item' value="Smoky Blue">Smoky Blue</button>
<button onClick={changeColor} className='item' value="Stratos Black">Stratos Black</button>
<button onClick={changeColor} className='item' value="Vitamin C">Vitamin C</button>
</div>
</div>
<div>
<input type="radio" name="accordion" id="Wood" className="accordion__input" />
<label htmlFor="Wood" className="materialLabel">Wood</label>
<div className="items">
<button onClick={changeColor} className='item' value="Golden Pecan Mappa Burl">Golden Pecan Mappa Burl</button>
<button onClick={changeColor} className='item' value="Golden Pecan Olive Ash">Golden Pecan Olive Ash</button>
<button onClick={changeColor} className='item' value="Natural Mappa Burl">Natural Mappa Burl</button>
<button onClick={changeColor} className='item' value="Natural Olive Ash">Natural Olive Ash</button>
<button onClick={changeColor} className='item' value="Provincial Mappa Burl">Provincial Mappa Burl</button>
<button onClick={changeColor} className='item' value="Provincial Olive Ash">Provincial Olive Ash</button>
</div>
</div>
</div>
现在我可以 console.log(product.material) 并查看产品 JSON,但我不确定如何提取该信息并将其插入
这是我用来获取 ProductDetails 的 redux/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,
});
}
};
如有任何帮助,我们将不胜感激!
为了简单起见,您应该创建一个自定义组件来表示您的输入收音机和循环
materials
对象列表- 其中的值列表
在ProductScreen
中:
{
product && product.materials[0].map((material) => (
<CustomRadioButton material={material} changeColor={changeColor} />
));
}
创建一个新的 CustomRadioButton
组件
export const CustomRadioButton = ({ material, changeColor }) => {
const materialName = Object.keys(material);
if (!materialName) return <></>;
return (
<div>
<input
type='radio'
name='accordion'
id={materialName}
className='accordion__input'
/>
<label htmlFor={materialName} className='materialLabel'>
{materialName}
</label>
<div className='items'>
{material[materialName].map((item) => (
<button onClick={changeColor} className='item' value={item}>
{item}
</button>
))}
</div>
</div>
);
};
好的,在@LuccaPizzini 的帮助下,我终于弄清楚了如何让它发挥作用! 这是我必须做的:
在Product Screen
中:
{
product && (product.materials ||).map((material, index) => (
<CustomRadioButton key={index} material={material} changeColor={changeColor} />
))
}
创建一个新的 CustomRadioButton
组件:
export const CustomRadioButton = ({ material, changeColor }) => {
const materialName = Object.keys(material);
if (!materialName) return <></>;
return (
<div>
<input
type='radio'
name='accordion'
id={materialName}
className='accordion__input'
/>
<label htmlFor={materialName} className='materialLabel'>
{materialName}
</label>
<div className='items'>
{material[materialName].map((item) => (
<button key={item} onClick={changeColor} className='item' value={item}>
{item}
</button>
))}
</div>
</div>
);
};
本质上,这两个组件与他提供的内容相比变化很小。