জেএস অনক্লিক ইভেন্ট হ্যান্ডলারকে প্রতিক্রিয়া জানান


120

আমার আছে

var TestApp = React.createClass({
      getComponent: function(){
          console.log(this.props);
      },
      render: function(){
        return(
             <div>
             <ul>
                <li onClick={this.getComponent}>Component 1</li>
             </ul>
             </div>
        );
      }
});
React.renderComponent(<TestApp />, document.body);

আমি ক্লিক তালিকার উপাদানটির পটভূমি রঙ করতে চাই। আমি কীভাবে প্রতিক্রিয়াতে এটি করতে পারি?

কিছুটা এইরকম

$('li').on('click', function(){
    $(this).css({'background-color': '#ccc'});
});

উত্তর:


95

কেন না:

onItemClick: function (event) {

    event.currentTarget.style.backgroundColor = '#ccc';

},

render: function() {
    return (
        <div>
            <ul>
                <li onClick={this.onItemClick}>Component 1</li>
            </ul>
        </div>
    );
}

এবং যদি আপনি এটি সম্পর্কে আরও প্রতিক্রিয়া-ধারণা হতে চান, আপনি বাছাই করা আইটেমটিকে তার প্রতিক্রিয়া উপাদানটির স্থিতি হিসাবে সেট করতে চাইতে পারেন, তারপরে আইটেমটির রঙ নির্ধারণের জন্য সেই রাষ্ট্রটি উল্লেখ করুন render:

onItemClick: function (event) {

    this.setState({ selectedItem: event.currentTarget.dataset.id });
    //where 'id' =  whatever suffix you give the data-* li attribute
},

render: function() {
    return (
        <div>
            <ul>
                <li onClick={this.onItemClick} data-id="1" className={this.state.selectedItem == 1 ? "on" : "off"}>Component 1</li>
                <li onClick={this.onItemClick} data-id="2" className={this.state.selectedItem == 2 ? "on" : "off"}>Component 2</li>
                <li onClick={this.onItemClick} data-id="3" className={this.state.selectedItem == 3 ? "on" : "off"}>Component 3</li>
            </ul>
        </div>
    );
},

আপনি <li>সেগুলিকে একটি লুপে রাখতে চান li.onএবং li.offআপনার স্টাইলগুলি আপনার সেট করা দরকার background-color


প্রতিক্রিয়াতে ম্যানুয়াল ডিওএম ম্যানিপুলেশন একটি অ্যান্টি-প্যাটার্ন যা কেবলমাত্র আরও সমস্যার দিকে নিয়ে যায়। event.currentTarget.style.backgroundColor = '#ccc';আপনি কী করছেন (আপনি তৃতীয় পক্ষের উইজেটগুলিকে একীভূত করার সময় বেশিরভাগ সময়) সত্যই বুঝতে না পারলে এ জাতীয় জিনিস এড়িয়ে চলুন ।
এমিল বার্গারন

61

দুটি উপায় আমি ভাবতে পারি are

var TestApp = React.createClass({
    getComponent: function(index) {
        $(this.getDOMNode()).find('li:nth-child(' + index + ')').css({
            'background-color': '#ccc'
        });
    },
    render: function() {
        return (
            <div>
              <ul>
                <li onClick={this.getComponent.bind(this, 1)}>Component 1</li>
                <li onClick={this.getComponent.bind(this, 2)}>Component 2</li>
                <li onClick={this.getComponent.bind(this, 3)}>Component 3</li>
              </ul>
            </div>
        );
    }
});
React.renderComponent(<TestApp /> , document.getElementById('soln1'));

এটা আমার ব্যক্তিগত প্রিয়।

var ListItem = React.createClass({
    getInitialState: function() {
        return {
            isSelected: false
        };
    },
    handleClick: function() {
        this.setState({
            isSelected: true
        })
    },
    render: function() {
        var isSelected = this.state.isSelected;
        var style = {
            'background-color': ''
        };
        if (isSelected) {
            style = {
                'background-color': '#ccc'
            };
        }
        return (
            <li onClick={this.handleClick} style={style}>{this.props.content}</li>
        );
    }
});

var TestApp2 = React.createClass({
    getComponent: function(index) {
        $(this.getDOMNode()).find('li:nth-child(' + index + ')').css({
            'background-color': '#ccc'
        });
    },
    render: function() {
        return (
            <div>
             <ul>
              <ListItem content="Component 1" />
              <ListItem content="Component 2" />
              <ListItem content="Component 3" />
             </ul>
            </div>
        );
    }
});
React.renderComponent(<TestApp2 /> , document.getElementById('soln2'));

এখানে একটি ডেমো রয়েছে

আশা করি এটা কাজে লাগবে.


8
রেন্ডার ফাংশনের মধ্যে বাইন্ডটি প্রয়োগ করার পরামর্শ দেওয়া হয় না কারণ এটি প্রতিবার উপাদানটি রেন্ডার হওয়ার পরে এটি করবে। আপনি এটিকে কিছু ফাংশনে নিয়ে যেতে পারেন যা জীবনচক্রের শুরুতে চলে
jony89

1
@ jony89 .bindঅতিরিক্ত প্যারামিটার না নিলে সম্মত হয়েছে । তবে প্রথম ক্ষেত্রে তা করে। আমি মনে করি না এর অন্য কোনও উপায় আছে
ধীরাজ

1
রয়েছে, তিনটি পৃথক ফাংশন তৈরি করুন (যা getComp घटक.bind (এটি, 1) এর ফলাফল দ্বারা তৈরি হয়েছে) যদিও এই সুনির্দিষ্ট সিদ্ধান্ত হতে পারে (এটি 2-3 এর জন্য নয়, 20 এর জন্য নয় - যদি না এটি সত্যই পারফরম্যান্সের সমস্যা হয়) এবং এটি গতিশীলভাবে তৈরি করা সহজ)।
jony89

38

এখানে ক্লিকের ইভেন্ট হ্যান্ডলারটি কীভাবে আপনি প্রতিক্রিয়ার সংজ্ঞা দেন যা প্রশ্নের শিরোনামের উত্তর দিচ্ছিল ... এস synt সিনট্যাক্স ব্যবহার করে

import React, { Component } from 'react';

export default class Test extends Component {
  handleClick(e) {
    e.preventDefault()
    console.log(e.target)
  }

  render() {
    return (
      <a href='#' onClick={e => this.handleClick(e)}>click me</a>
    )
  }
}

9
উভয়ই bindবা তীর ফাংশনগুলি renderপদ্ধতিগুলির মধ্যে ব্যবহার করা উচিত নয় কারণ এগুলি প্রতিবারই একটি নতুন ফাংশন তৈরি হওয়ার ফল দেয়। এটির উপাদানগুলির স্থিতি পরিবর্তন করার প্রভাব রয়েছে এবং পরিবর্তিত রাজ্যের উপাদানগুলি সর্বদা পুনরায় রেন্ডার করা হয়। একক জন্য aএটি কোনও বড় কথা নয়। ক্লিকযোগ্যযোগ্য আইটেমগুলির সাথে উত্পন্ন তালিকাগুলির জন্য এটি খুব দ্রুত একটি বড় চুক্তিতে পরিণত হয়। এ কারণেই এর বিরুদ্ধে বিশেষভাবে সতর্ক করা হয়েছে।
হিপ্পিট্রেইল

18

ECMA2015 ব্যবহার করুন। তীর ফাংশনগুলি "এটি" কে অনেক বেশি স্বজ্ঞাত করে তোলে।

import React from 'react';


class TestApp extends React.Component {
   getComponent(e, index) {
       $(e.target).css({
           'background-color': '#ccc'
       });
   }
   render() {
       return (
           <div>
             <ul>
               <li onClick={(e) => this.getComponent(e, 1)}>Component 1</li>
               <li onClick={(e) => this.getComponent(e, 2)}>Component 2</li>
               <li onClick={(e) => this.getComponent(e, 3)}>Component 3</li>
             </ul>
           </div>
       );
   }
});
React.renderComponent(<TestApp /> , document.getElementById('soln1'));`

2
indexএখানে কিছু করে না?
আমেরিকান

@ উত্তর আমেরিকান - না, ঠিক আছে কিছু প্যারামিটারের স্পষ্টতা যোগ করার জন্য
itcropper

5
এটি কার্য সম্পাদনের জন্য খারাপ কারণ এটি প্রতিটি রেন্ডারের উপর একটি নতুন ফাংশন তৈরি করে। দেখুন: stackoverflow.com/questions/36677733/...
Jochie Nabuurs

1
এবং দয়া করে প্রতিক্রিয়া ভিতরে jQuery ব্যবহার করবেন না যদি আপনি না করেন!
এমিল বার্গারন

13

আপনি যদি ES6 ব্যবহার করে থাকেন তবে এখানে কয়েকটি সাধারণ উদাহরণ কোড রয়েছে:

import React from 'wherever_react_is';

class TestApp extends React.Component {

  getComponent(event) {
      console.log('li item clicked!');
      event.currentTarget.style.backgroundColor = '#ccc';
  }

  render() {
    return(
       <div>
         <ul>
            <li onClick={this.getComponent.bind(this)}>Component 1</li>
         </ul>
       </div>
    );
  }
}

export default TestApp;

ES6 শ্রেণীর সংস্থায়, ফাংশনগুলির জন্য আর 'ফাংশন' কীওয়ার্ডের প্রয়োজন হয় না এবং তাদের কমা দ্বারা আলাদা করার প্রয়োজন হয় না। আপনি ইচ্ছে করলে => সিনট্যাক্সটিও ব্যবহার করতে পারেন।

গতিশীলভাবে তৈরি উপাদানগুলির সাথে এখানে একটি উদাহরণ রয়েছে:

import React from 'wherever_react_is';

class TestApp extends React.Component {

constructor(props) {
  super(props);

  this.state = {
    data: [
      {name: 'Name 1', id: 123},
      {name: 'Name 2', id: 456}
    ]
  }
}

  getComponent(event) {
      console.log('li item clicked!');
      event.currentTarget.style.backgroundColor = '#ccc';
  }

  render() {        
       <div>
         <ul>
         {this.state.data.map(d => {
           return(
              <li key={d.id} onClick={this.getComponent.bind(this)}>{d.name}</li>
           )}
         )}
         </ul>
       </div>
    );
  }
}

export default TestApp;

নোট করুন যে প্রতিটি গতিশীলভাবে তৈরি উপাদানটির একটি অনন্য রেফারেন্স 'কী' হওয়া উচিত।

তদ্ব্যতীত, আপনি যদি নিজের অন ক্লিক ফাংশনে প্রকৃত ডেটা অবজেক্ট (ইভেন্টের চেয়ে) পাস করতে চান তবে আপনাকে এটি আপনার বাইন্ডে পাস করতে হবে। উদাহরণ স্বরূপ:

নতুন অনক্লিক ফাংশন:

getComponent(object) {
    console.log(object.name);
}

ডেটা অবজেক্টে পাস করা:

{this.state.data.map(d => {
    return(
      <li key={d.id} onClick={this.getComponent.bind(this, d)}>{d.name}</li>
    )}
)}

আমি আমার লি আইটেমগুলিকে গতিশীল করার চেষ্টা করছি এবং তারপরে এটি অনির্ধারিত হয়ে যায় এবং অনক্লিক ফাংশন তাই ত্রুটি ছুঁড়ে দেয়।
অবতরণ করেছে

1
আমি সবেমাত্র একটি অনুরূপ উত্তর পেয়েছি যেখানে আপনার .bind (এটি)) ব্যবহার করা দরকার; বেনামে ফাংশন শেষে আপনার
অবতরণ করেছেন


6

প্রতিক্রিয়া উপাদানগুলির সাথে ইভেন্টগুলি পরিচালনা করা DOM উপাদানগুলিতে ইভেন্টগুলি পরিচালনা করার সাথে খুব মিল। কিছু সিনথেটিক পার্থক্য রয়েছে:

  • প্রতিক্রিয়া ইভেন্টগুলি ছোট হাতের চেয়ে বরং উটকেস ব্যবহার করে নামকরণ করা হয়।
  • জেএসএক্সের সাহায্যে আপনি স্ট্রিংয়ের পরিবর্তে ইভেন্ট হ্যান্ডলার হিসাবে কোনও ফাংশন পাস করেন।

রি্যাক্ট ডকুমেন্টেশনে যেমন উল্লেখ করা হয়েছে , ইভেন্ট হ্যান্ডলিংয়ের ক্ষেত্রে এগুলি সাধারণ HTML এর মতোই একই রকম, তবে ইভেন্টের নামগুলি ক্যামেলকেস ব্যবহার করে প্রতিক্রিয়া দেখায়, কারণ তারা সত্যই এইচটিএমএল নয়, এগুলি জাভাস্ক্রিপ্ট, এছাড়াও, আমরা ফাংশন কলটি পাস করার সময় আপনি ফাংশনটি পাস করেন এইচটিএমএল-এর স্ট্রিং ফর্ম্যাটে এগুলি ভিন্ন, তবে ধারণাগুলি বেশ একই রকম ...

নীচের উদাহরণটি দেখুন, কীভাবে ইভেন্টটি কার্যক্রমে পাস হবে সেদিকে মনোযোগ দিন:

function ActionLink() {
  function handleClick(e) {
    e.preventDefault();
    console.log('The link was clicked.');
  }

  return (
    <a href="#" onClick={handleClick}>
      Click me
    </a>
  );
}

3

import React from 'react';

class MyComponent extends React.Component {

  getComponent(event) {
      event.target.style.backgroundColor = '#ccc';
      
      // or you can write
      //arguments[0].target.style.backgroundColor = '#ccc';
  }

  render() {
    return(
       <div>
         <ul>
            <li onClick={this.getComponent.bind(this)}>Component 1</li>
         </ul>
       </div>
    );
  }
}

export { MyComponent };  // use this to be possible in future imports with {} like: import {MyComponent} from './MyComponent'
export default MyComponent;


এটি মূলত 11 দফা উত্তরের মতো অভিন্ন বলে মনে হচ্ছে এবং চমত্কার বা প্রশ্ন-কেন পুনরুত্থিত হবে?
ডেভ নিউটন

2

class FrontendSkillList extends React.Component {
  constructor() {
    super();
    this.state = { selectedSkill: {} };
  }
  render() {
    return (
      <ul>
        {this.props.skills.map((skill, i) => (
            <li
              className={
                this.state.selectedSkill.id === skill.id ? "selected" : ""
              }
              onClick={this.selectSkill.bind(this, skill)}
              style={{ cursor: "pointer" }}
              key={skill.id}
            >
            {skill.name}
            </li>
        ))}
      </ul>
    );
  }

  selectSkill(selected) {
    if (selected.id !== this.state.selectedSkill.id) {
      this.setState({ selectedSkill: selected });
    } else {
      this.setState({ selectedSkill: {} });
    }
  }
}

const data = [
  { id: "1", name: "HTML5" },
  { id: "2", name: "CSS3" },
  { id: "3", name: "ES6 & ES7" }
];
const element = (
  <div>
    <h1>Frontend Skill List</h1>
    <FrontendSkillList skills={data} />
  </div>
);
ReactDOM.render(element, document.getElementById("root"));
.selected {
  background-color: rgba(217, 83, 79, 0.8);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

<div id="root"></div>

@ ব্যবহারকারী544079 আশা করি এই ডেমোটি সহায়তা করতে পারে :) আমি ক্লাসের নাম টগল করে পটভূমির রঙ পরিবর্তন করার পরামর্শ দিচ্ছি।


2

import React from 'react';

class MyComponent extends React.Component {

  getComponent(event) {
      event.target.style.backgroundColor = '#ccc';
      
      // or you can write
      //arguments[0].target.style.backgroundColor = '#ccc';
  }

  render() {
    return(
       <div>
         <ul>
            <li onClick={this.getComponent.bind(this)}>Component 1</li>
         </ul>
       </div>
    );
  }
}

export { MyComponent };  // use this to be possible in future imports with {} like: import {MyComponent} from './MyComponent'
export default MyComponent;


এটি কীভাবে এটি সমস্যার সমাধান করতে পারে তা ব্যাখ্যা করে আপনি এই কোডটির আরও প্রসঙ্গ সরবরাহ করতে পারেন?
এমইডিজেড

1

আপনি React.createClone পদ্ধতিটি ব্যবহার করতে পারেন। এটির ক্লোন তৈরি করার চেয়ে আপনার উপাদানটি তৈরি করুন। ক্লোন তৈরির সময়, আপনি প্রপস ইনজেক্ট করতে পারেন। একটি অনক্লিক: পদ্ধতি প্রপ এইভাবে ইনজেক্ট করুন

{ onClick : () => this.changeColor(originalElement, index) }

পরিবর্তন কালার পদ্ধতিটি নকলের সাথে রাজ্যটি সেট করবে, আপনাকে প্রক্রিয়াটিতে রঙ সেট করতে দেয়।

render()
  {
    return(
      <ul>

        {this.state.items.map((val, ind) => {
          let item = <li key={ind}>{val}</li>;
          let props = { 
            onClick: () => this.Click(item, ind),
            key : ind,
            ind
          }
          let clone = React.cloneElement(item, props, [val]);
          return clone;
        })}

      </ul>
    )
  }


ক্লোনিং সম্পূর্ণ অপ্রয়োজনীয়।
এমিল বার্গারন

-17

এটি একটি অ-মানক (তবে এতটা অস্বাভাবিক নয়) এর প্রতিক্রিয়া প্যাটার্ন যা জেএসএক্স ব্যবহার করে না, পরিবর্তে সবকিছুকে ইনলাইন করে। এছাড়াও, এটি কফিস্ক্রিপ্ট।

এটি করার জন্য 'প্রতিক্রিয়া-উপায়' উপাদানটির নিজস্ব রাষ্ট্রের সাথে থাকবে:

( c = console.log.bind console)

mock_items: [
    {
        name: 'item_a'
        uid: shortid()
    }
    {
        name: 'item_b'
        uid: shortid()
    }
    {
        name: 'item_c'
        uid: shortid()
    }
]
getInitialState: ->
    lighted_item: null
render: ->
    div null,
        ul null,
            for item, idx in @mock_items
                uid = item.uid
                li
                    key: uid
                    onClick: do (idx, uid) =>
                        (e) =>
                            # justf to illustrate these are bound in closure by the do lambda,
                            c idx
                            c uid
                            @setState
                                lighted_item: uid
                    style:
                        cursor: 'pointer'
                        background: do (uid) =>
                            c @state.lighted_item
                            c 'and uid', uid
                            if @state.lighted_item is uid then 'magenta' else 'chartreuse'
                        # background: 'chartreuse'
                    item.name

এই উদাহরণটি কাজ করে - আমি এটি স্থানীয়ভাবে পরীক্ষা করেছি। আপনি আমার গিথুবে এই উদাহরণ কোডটি চেক করতে পারেন । মূলত envটি কেবলমাত্র আমার নিজের হোয়াইটবোর্ডের জন্য & র উদ্দেশ্যে স্থানীয় ছিল তবে আমি এটির জন্য এটি গিথুবকে পোস্ট করেছি। এটি কোনও সময়ে লিখিত হতে পারে তবে আপনি এটি দেখতে 8 সেপ্টেম্বর, 2016 থেকে প্রতিশ্রুতিটি দেখতে পারেন।

আরও সাধারণভাবে, আপনি কীভাবে প্রতিক্রিয়াটির জন্য এই সিএস / নো-জেএসএক্স প্যাটার্নটি দেখতে চান তা এখানে কিছু সাম্প্রতিক কাজ পরীক্ষা করে দেখুন । এটি সম্ভব এই অ্যাপ্লিকেশন ধারণার জন্য একটি পোকি সম্পূর্ণরূপে প্রয়োগ করার সময় পাব, যার মধ্যে নোডজেএস, প্রিমাস, রেডিস এবং প্রতিক্রিয়া রয়েছে।


পটভূমিটি doল্যাম্বডা হওয়ার দরকার নেই : এই অভিব্যক্তিটিও কাজ করে:background: if @state.lighted_item is uid then 'magenta' else 'chartreuse'
ওয়াইলি কুলিক

হ্যালো আমি ব্রাউজার কনসোলে অনক্লিক দেখতে পারি কীভাবে?
মুনিম হাবিব

12
কেন আপনি কোনও প্রশ্নের উত্তরে কফি স্ক্রিপ্টটি ব্যবহার করবেন না যা কোনওভাবেই এটি উল্লেখ করে না? এটি কোনও অর্থবোধ করে না এবং এটি সম্ভবত উত্তরদাতাকে পড়ার জন্য উত্তরটি আরও শক্ত করে তুলতে পারে, কারণ তিনি কফি স্ক্রিপ্টের মতো / জানেন না। ডাউনভোটিং, স্পষ্টতই।
ম্যাকবেম

7
না তবে এটি ভাষার উপরে নির্মিত এমন কিছু যা নিখুঁতভাবে মানক নয় এবং এটি ইনস্টলিং এবং সংকলন প্রয়োজন। যখন জিরো তাদের প্রকল্পে কফিস্ক্রিপ্ট ব্যবহার করছে এমন সমস্ত বিষয়ে ইঙ্গিত দিচ্ছে তখন আপনার উত্তরটি কফিস্ক্রিপ্টে লিখতে সত্যই দুর্বল পছন্দ ছিল
TheRealMrCrowley

4
কফিসক্রিপ্টটি জেএস এর উপরে কেবল একটি স্তর । FTFY।
মেশিনঘস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.