Tengo datos asignados en un componente como este:
import React from "react"; import { useState } from "react"; import { useEffect } from "react"; import { get } from "lodash"; const Products = ({ data }) => { return ( data.map((item, index) = > ( <div id={index}> <img src={item.img} /> <br /> {item.name} <br /> {get(moreData, `[${item.name.toLowerCase()}].info[0]`)} {get(moreData, `[${item.name.toLowerCase()}].info[1]`)} {get(moreData, `[${item.name.toLowerCase()}].info[2]`)} </div>Quiero poder almacenar estos datos:
{item.name} {get(moreData, `[${item.name.toLowerCase()}].info[0]`)} {get(moreData, `[${item.name.toLowerCase()}].info[1]`)} {get(moreData, `[${item.name.toLowerCase()}].info[2]`)} en una cadena, como string = {item.name},{moreData.item.name.toLowerCase().info[0]},...//etc
Sin embargo, no puede declarar variables dentro de un componente (que yo sepa, todavía es nuevo en esto).
.concat() - después de cada línea y .push() con matriz en lugar de cadena:
{item.name} <br /> {dataString.concat(item.name)} {dataArr.push(item.name)} {get(moreData, `[${item.name.toLowerCase()}].info[0]`)} {get(moreData, `[${item.name.toLowerCase()}].info[1]`)} {get(moreData, `[${item.name.toLowerCase()}].info[2]`)}Iba a usar DOM, pero me dijeron que es una mala práctica usar DOM en reaccionar.
También he intentado usar el estado de la misma manera:
const [dataString, setDataString] = useState(""); ...
{item.name} {setDataString((dataString += item.name))}Pero nada parece funcionar según lo previsto para mí, y no tengo ideas.
Editar:
Quiero poder copiar la 'cadena/texto' al portapapeles eventualmente. Por lo tanto, se puede importar a otro sitio. Su formato requerido es Item1, item1-info1, item1-info2, item1-info3, item2, item2-info1, item2-info2, item2-info3...etc
aquí hay un ejemplo de cómo puede usar el objeto de datos fuera de los objetos asignados. también un ejemplo de cómo convertir los datos a una cadena en el formato requerido. porque no conozco la estructura del objeto de datos suyo, acabo de crear uno, tome este código y cámbielo a la estructura de datos
const data = [ { name: "name1", info1: "info1-1", info2: "info1-2", info3: "info1-3", }, { name: "name2", info1: "info2-1", info2: "info2-2", info3: "info2-3", }, { name: "name3", info1: "info3-1", info2: "info3-2", info3: "info3-3", }, ];cambie esta función a una que se ajuste a sus necesidades.
const getStringOfData = (data) => { let stringArray = []; data.map((item) => { stringArray.push(item.name); stringArray.push(item.info1); stringArray.push(item.info2); stringArray.push(item.info3); }); let stringResult = stringArray.join(","); return stringResult; }; useEffect(() => { console.log("onMounte with useEffect"); let stringResult = getStringOfData(data) console.log(stringResult); }, []);también puede llamar a esta función en la función onClick dependiendo de sus requisitos, el objeto de datos está disponible en casi todas partes en su componente
Continuando con nuestra discusión de los comentarios, parece que hay dos cosas diferentes que está tratando de hacer aquí:
Aconsejaría dividir estos dos comportamientos, porque no tienen ninguna relación entre sí en términos lógicos.
Comience alineando la información en sus componentes como la necesita.
const Product = ({ item, index }) => { // do whatever you need to do with the information // to display it correctly const identifier = name.toLowerCase() const infos = (moreData[identifier] && moreData[identifier].info) || {} return ( <div> { info[0] && <p> info[0] </p>} { info[1] && <p> info[1] </p>} { info[1] && <p> info[2] </p>} </div> ) } const Products = ({ data }) => { const onClick = useCallback( async () => { // parse data and copy it using a separate // util method. const dataToString = /* actual implementation of the formatting to a string representation */ copyTextToClipBoard(dataToString) }, [data] ) return ( <div> <button onClick={onClick} /> <div> data.map((item, index) => ( <Product item={item} index={index} key={item.id} /> )) </div> </div> ) };Ahora, esta sería su interfaz de usuario, el método copyToClipboard, es un truco y se ve así:
const copyTextToClipBoard = (text) => { const element = document.createElement('textarea'); element.style = { display: 'none' }; // eslint-disable-line element.value = text; document.body.appendChild(element); element.select(); document.execCommand('copy'); document.body.removeChild(element); };