3

I'm mapping over an array to get the text for each button. I want to map over an array for each button to show text for a mapped array.

So the array for the titles of the button is:

const arr1 = ["one", "two", "three"]

And the text to show when each button is clicked is:

const arr2 = ["button one", "button two", "button three"]

So I want button with the text "one" to show the text "button one" as a p tag when clicked.

Here is what I have so far

const myComp = () => {
    const arr1 = ['one', 'two', 'three']

    const arr2 = ['button one', 'button two', 'button three']

    const mapping = () => {
        arr2.map((arr) => {
            return <p>{arr}</p>
        })
    }
    return (
        <>
            {arr1.map((data) => 
                <button onClick={mapping()}>
                    {data}
                </button>
            )}
        </>
)

4 Answers 4

4

With hooks, put the current button text into a <p> inside the JSX being returned, and inside the click callback, set the text to the same index in arr2:

const MyComp = () => {
    const [text, setText] = useState('');
    const arr1 = ['one', 'two', 'three']

    const arr2 = ['button one', 'button two', 'button three']

    const mapping = () => {
        arr2.map((arr) => {
            return <p>{arr}</p>
        })
    }
    return (
        <>
            {arr1.map((data, i) =>
                <button onClick={() => setText(arr2[i])}>
                    {data}
                </button>
            )}
            <p>{text}</p>
        </>
    );
};

Live snippet:

const MyComp = () => {
    const [text, setText] = React.useState('');
    const arr1 = ['one', 'two', 'three']

    const arr2 = ['button one', 'button two', 'button three']

    const mapping = () => {
        arr2.map((arr) => {
            return <p>{arr}</p>
        })
    }
    return (
        <React.Fragment>
            {arr1.map((data, i) =>
                <button onClick={() => setText(arr2[i])}>
                    {data}
                </button>
            )}
            <p>{text}</p>
        </React.Fragment>
    );
};

ReactDOM.render(
  <MyComp />,
  document.getElementById("react")
);
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="react"></div>

Sign up to request clarification or add additional context in comments.

Comments

1
    You can try this way as it makes a key/value pair hence would be easy to link both button and its value.

    var testArr = arr2.map(function(item,index) { 
            return {"id":arr1[index], "val":item}
        }.bind(this));

        console.log(testArr);

        Output:
        [{
           id: "one",
           val: "button one"
         }, {
              id: "two",
              val: "button two"
         }, {
              id: "three",
              val: "button three"
        }]

Comments

0

You can also create an array with objects

const items = [{num : 'one', text: 'btn one'}, ...]

Then to make smth like this

const [text, setText] = useState(null)
const showText = (text) => {
  setText(text);
}
return <>
{
   items.map(obj => <button onClick={() => showText(obj.text)}>{obj.num}</button>)
}
{
  text && <span>{text}</span>
}
</>

Comments

0

Here is how you would do this by keeping the same structure that you've currently got.

import React, { useState, useEffect } from 'react';

const MyComp = () => {
  const [buttonsClicked, setButtonsClicked] = useState([]);

  const arr1 = ["one", "two", "three"];
  const arr2 = ["button one", "button two", "button three"];

  useEffect(() => {
    // Create an array with the same amount of values
    // as the arr1 variable and initiate all values
    // as false
    const initialButtonsClicked = arr1.map(() => false);

    setButtonsClicked(initialButtonsClicked);
  }, []);

  const handleClick = index => {
    // Find and set the value of the button clicked to true
    // leaving the rest as they were
    setButtonsClicked(prev =>
      prev.map((item, buttonIndex) => (buttonIndex === index ? true : item))
    );
  };

  return (
    <>
      {arr1.map((_, index) => (
        <button
          key={index}
          onClick={() =>
            handleClick(index)
          }
        >
          {buttonsClicked[index] && arr2[index]}
        </button>
      ))}
    </>
  );
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.