Home > front end >  Show a component in another component when button is clicked
Show a component in another component when button is clicked

Time:09-29

I want to view information from a dummy module when I click a component. I have tried a few methods but i'm pretty new to react so i haven't had any success.

I have one component that projects some of the information of each element in the module as a list, and I want to be able to click it, and show extended information of that specific element in another component.

So far this is what i have:

ListOfData.tsx

import React from 'react'
import '../css/ListOfData.css'
import ListOfDataElement from "./ListOfDataElement";
import DummyListContent from "./DummyListContent";
function ListOfData() {
    const dataComponent = DummyListContent.map(item => <ListOfDataElement key={item.id} product={item}/>)

    return (
        <div className="ListOfData_container">
            {dataComponent}
        </div>
    )
}

export default ListOfData

ListOfDataElements.tsx

import React from "react";
import '../css/ListOfData.css'
function ListOfDataElement(props: any) {
    return(
        <div className={'ListOfDataElement'} onClick={() => alert('test')}>
            <h3>{props.product.id} - {props.product.name}<i className={'arrow right'}/></h3>
        </div>
    )
}
export default ListOfDataElement

InfoOfData.tsx

import React from 'react'
import '../css/InfoOfData.css'

function InfoOfData() {

    return (
        <div className="InfoOfData_container" id="InfoContainer">

        </div>
        )

}

export default InfoOfData

InfoOfDataElement.tsx

import React from "react";

function InfoOfDataElement(props:any) {

    return(
        <div className={'ListOfDataElement'}>
            <h3>{props.product.name}</h3>
            <h4>Spent: {props.product.spent}</h4>
            <p>Description: {props.product.description}</p>
        </div>
    )

}
export default InfoOfDataElement

DummyListContent.tsx

const content = [
    {
        id: "#1",
        name: "Placeholder",
        spent: 1,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#2",
        name: "Placeholder",
        spent: 4,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#3",
        name: "Placeholder",
        spent: 1,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#4",
        name: "Placeholder",
        spent: 2,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#5",
        name: "Placeholder",
        spent: 1,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#6",
        name: "Placeholder",
        spent: 3,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#7",
        name: "Placeholder",
        spent: 5,
        description: "Placeholder Placeholder Placeholder Placeholder."
    },
    {
        id: "#8",
        name: "Placeholder",
        spent: 4,
        description: "Placeholder Placeholder Placeholder Placeholder."
    }
]

export default content

My goal is to make InfoOfDataElement show the rest of the information for the clicked ListOfDataElement element, and render it inside InfoOfData.

CodePudding user response:

I'm new to react myself and I didn't understand 100% what you wanted to do, but ill do my best to help you achieve what you are trying to do, if you want to render a component in react you have few ways, changing local state is one of the easiest ways, in the next example (I don't know if it works! I may miss something) I used state for the data and that will render the component as well so if you pass a state the button will get the new state as well and trigger a render.

import React from 'react'
import '../css/InfoOfData.css'

function InfoOfData() {
const [state,myState] = useState(//the data to transfer)

    return (
        <div className="InfoOfData_container" id="InfoContainer">
           <button onClick={()=><InfoOfDataElement props={state}/>}
        </div>
        )

}

export default InfoOfData

CodePudding user response:

Try this:

import React from 'react'
import '../css/ListOfData.css'
import ListOfDataElement from "./ListOfDataElement";
import DummyListContent from "./DummyListContent";

function ListOfData() {
    return (
      <div>

     {
       DummyListContent.map((item,key) => {
         return (
           <div className='container' key={item.id}>
             <ListOfDataElement id={item.id} product={item}/>
           </div>
         )
       }
    )
}

export default ListOfData;
import React from "react";
import '../css/ListOfData.css'
function ListOfDataElement({ product }) {
    return(
        <div className={'ListOfDataElement'} onClick={() => alert('test')}>
            <h3>{id} - {name}<i className={'arrow right'}/></h3>
        </div>
    )
}
export default ListOfDataElement

CodePudding user response:

Here's a code sandbox working as I assume you want it to work. Sandbox

Well basically you would need a state to hold the selected element.

Assume you click on the button, then you would trigger a callback to change the state of the parent component (App) and since we pass the selected state as props to the children (ListOfData, InfoOfData, etc...) React would automatically pickup the state change and re render the content in InfoOfData and it's child InfoOfDataElement.

I just left out the button part but as long as you had a button and change the onClick event to that button it will work.

CodePudding user response:

InfoOfData component has state with selected product and pass function onSelectItem to children item on the list

import React from 'react'
import DummyListContent from "./DummyListContent";
import InfoOfDataElement from "./InfoOfDataElement";
import ListOfData from "./ListOfData";
import '../css/InfoOfData.css'

function InfoOfData() {

    const [selected, setSelected] = useState(null);

    const onSelectItem = (item) => {
        setSelected(item);
    }

    return (
        <div className="InfoOfData_container" id="InfoContainer">
            {selected && <InfoOfDataElement product={selected} />} // Render if product is on state
            <ListOfData onSelect={onSelectItem} /> // There we pass function as prop
            
        </div>
        )

}

export default InfoOfData

List pass onSelect as prop to children

import React from 'react'
import '../css/ListOfData.css'
import ListOfDataElement from "./ListOfDataElement";

function ListOfData(props) {
    const { list = [], onSelect } = props; // pass list
    const dataComponent = list.map(item => <ListOfDataElement key={item.id} product={item} onSelect={onSelect} />)

    return (
        <div className="ListOfData_container">
            {dataComponent}
        </div>
    )
}

export default ListOfData

List item call function onSelect with product to Parent

import React from "react";
import '../css/ListOfData.css'
function ListOfDataElement(props: any) {
    const { onSelect, product } = props;

    const onSelectProduct = () => onSelect(product); // Call prop function onSelect

    return(
        <div className={'ListOfDataElement'} onClick={onSelectProduct}>
            <h3>{props.product.id} - {props.product.name}<i className={'arrow right'}/></h3>
        </div>
    )
}
export default ListOfDataElement

Please check all imports and props

  • Related