2

I'd like to get specific an array with onClick but the results always is undefined. if the explanation is unclear, tell me please. i will fix it ! Thanks here is the code

 const chartType = ["Line", "Bar", "Pie", "Radar", "Doughnut", "Bubble"];
  const getType = (e) => {
    if (e.currentTarget === "Line") {
      console.log("true");
    }
  };
  const typeList = chartType.map((chart) => (
    <div>
      <h1 onClick={getType}>{chart}</h1>
    </div>
  ));

u guys really helped me to solve this !! I appreciate it so much !! I hope u all have a really nice day !!

2
  • 1
    what you mean by undefined ? can you paste the full code ? . Also what do you get when you do console.log(e.currentTarget) ? Commented May 27, 2021 at 13:48
  • I'm sorry aha i got the right answer from the other one ! thank u so much taking the time for answering ! Commented May 27, 2021 at 13:57

4 Answers 4

3

your onClick is actually grabbing the html element, that's why you're not getting any matches, when you click a particular h1, it returns <h1>Foo</h1>. To get the correct target you need e.currentTarget.innerText. Also since you are using React, please add a unique key prop to the iterated items.

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

5 Comments

Omg Thank u so much !! i solved the problem and i will add a uniquekey props now !
Sir , and i have another curious thing, why do i have to add a unique key?? i've been wondering why u add it. if u have time to answer, please feel free !
To avoid React complaining in the console 😅. Just kidding, the real reason to add it is that they help "identify which items have changed, are added, or are removed". It's just a little marker for React to render your components more efficiently. If you want to read a little more, check out reactjs.org/docs/lists-and-keys.html
Do not use innerText, because it is performance-heavy (as is calculates CSS). Just stick with using textContent.
omg Thank u so much !! you guys so helped me a lot !
1

When onClick event happen, it fires MouseEvent (you can see it when use console.log(e) from getType function). If you want to pass custom parameters, you should do like the following example:

  const chartType = ["Line", "Bar", "Pie", "Radar", "Doughnut", "Bubble"];
  const getType = (type) => {
    if (type === "Line") {
      console.log("true");
    }
  };
  const typeList = chartType.map((chart) => (
    <div>
      <h1 onClick={() => getType(chart)}>{chart}</h1>
    </div>
  ));

Comments

1

e.currentTarget returns the entire tag for example you will get this

<h1>Line</h1>

what you can do instead is to pass the chart as the argument to the getType.

const getType = (chart) => {
    if (chart === "Line") {
      console.log("true");
    }
  };

  const typeList = chartType.map((chart) => (
    <div>
      <h1 onClick={() => getType(chart)}>{chart}</h1>
    </div>
  ));

1 Comment

Oh that's another good solution !! thank u so much !!
1

If you want to change the chart type, you can use the useState hook to store the active state.

Edit: I changed target.textContent to target.dataset.chartType and added the data attribute called data-chart-type to each <h1>. This is safer than using rendered text.

const { useState } = React;

const ChartTypes = ['Line', 'Bar', 'Pie', 'Radar', 'Doughnut', 'Bubble'];

const ChartTypeList = (props) => {
  const { activeType, handleSelect } = props;

  return (
    <div className="ChartTypeList">
      {ChartTypes.map((chartType) => (
        <h1
          key={chartType}
          className={activeType === chartType ? 'active' : ''}
          data-chart-type={chartType}
          onClick={handleSelect}>
            {chartType}
        </h1>
      ))}
    </div>
  );
};

const App = () => {
  const [activeType, setActiveType] = useState(null);

  const handleSelect = ({ target }) => {
    setActiveType(target.dataset.chartType);
    console.log(`Changed type: "${target.dataset.chartType}"`);
  };

  return (
    <div className="App">
      <ChartTypeList activeType={activeType} handleSelect={handleSelect} />
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById('react'));
.as-console-wrapper { max-height: 4em !important; }

.App > .ChartTypeList {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  justify-content: center;
  align-items: center;
}

.ChartTypeList h1 {
  color: grey;
  font-size: 1em;
  font-style: italic;
  text-align: center;
}

.ChartTypeList h1:hover {
  color: blue;
  text-decoration: underline;
  cursor: pointer;
}

.ChartTypeList h1.active {
  color: unset;
  font-style: unset;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>

2 Comments

omg ! that's what i wanna do now !! thank u so much !!
@KYUN the best way to approach this is to divide and conquer. Design your components as small building blocks.

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.