DeadOnBullseye
DeadOnBullseye

Reputation: 45

How to use onClick in imported .map() react.js

Ok so I have two files Test.js and Test2.js

Test.js:

import React from 'react';

const hello = ['hello', 'hi', 'sup'];

export const helloWorld = hello.map(helloCode => {
  return (
    <button onClick={this.handleClick}>{helloCode}</button>
  );
});

Test2.js:

import React from 'react';
import { helloWorld } from './Test';

export class RealTest extends React.Component {

  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick() {
    console.log('clicked');
  }

  render() {

    return (
      <div>
           {helloWorld}
      </div>
    );
  }
};

I can't figure out how to get helloWorld to access the onClick function, I have tried to create a props, I have tried binding it, but I cannot get it to work unless it is in Test2.js, but I need it to be in it's own seperate file. Thanks for the help.

Upvotes: 0

Views: 117

Answers (3)

Tareq
Tareq

Reputation: 5363

const hello = ['hello', 'hi', 'sup'];

const HelloWorld = (props) => <div>{hello.map(name =>(<button onClick={() => props.handleClick(name)}>{name}</button>))}</div>


class RealTest extends React.Component {
  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(name) {
    console.log('clicked for name ', name);
  }

  render() {

    return (
      <div>
           <HelloWorld handleClick={this.handleClick} />
      </div>
    );
  }
};

ReactDOM.render(
  <RealTest/>,
  document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>

Upvotes: 0

azium
azium

Reputation: 20614

@Adam suggesting passing the context down, but I think it's more React like to pass props.

export const HelloWorld = props => hello.map(helloCode => {
  return (
    <button 
      key={helloCode} // <--- make sure to add a unique key
      onClick={props.handleClick}
    >
      {helloCode}
    </button>
  );
});

Then render:

 <div>
    <HelloWorld handleClick={this.handleClick} />
 </div>

Upvotes: 1

Adam Jenkins
Adam Jenkins

Reputation: 55623

The array of JSX accessed via the variable helloWorld does not have any knowledge of what you want the context (e.g. this) to be when it's in it's own file (and, thus, this.handleClick can't be used).

The simplest way is to make it a function so you can pass the correct context:

import React from 'react';

const hello = ['hello', 'hi', 'sup'];

export const helloWorld = (context) => hello.map(helloCode => {
  return (
    <button onClick={context.handleClick}>{helloCode}</button>
  );
});

and then in your render method, pass in the context:

render() {

    return (
      <div>
           {helloWorld(this)}
      </div>
    );

}

Upvotes: 0

Related Questions