প্রতিক্রিয়া: কীভাবে গতিশীল শিশু উপাদান রাষ্ট্র বা পিতামাতার কাছ থেকে প্রপস পরিবর্তন করতে হয়?


90

আমি মূলত প্রতিক্রিয়াতে ট্যাবগুলি তৈরি করার চেষ্টা করছি তবে কিছু সমস্যা রয়েছে।

এখানে ফাইল page.jsx

<RadioGroup>
    <Button title="A" />
    <Button title="B" />
</RadioGroup>

আপনি যখন বোতাম এ ক্লিক করেন, রেডিওগোষ্ঠী উপাদানটি বোতাম বি-নির্বাচন করতে হবে

"নির্বাচিত" এর অর্থ একটি রাজ্য বা সম্পত্তি থেকে শ্রেণি নাম

এখানে RadioGroup.jsx:

module.exports = React.createClass({

    onChange: function( e ) {
        // How to modify children properties here???
    },

    render: function() {
        return (<div onChange={this.onChange}>
            {this.props.children}
        </div>);
    }

});

এর উত্সটি Button.jsxআসলেই কিছু যায় আসে না, এর একটি নিয়মিত এইচটিএমএল রেডিও বোতাম রয়েছে যা নেটিভ ডোম onChangeইভেন্টটিকে ট্রিগার করে

প্রত্যাশিত প্রবাহটি হ'ল:

  • বোতাম "এ" এ ক্লিক করুন
  • বোতাম "এ" টি নেভিগেশন ডেমো ইভেন্ট, চেঞ্জকে ট্রিগার করে যা রেডিওগোষ্ঠী পর্যন্ত বুদবুদ হয়
  • রেডিওগ্রুপ অন চেঞ্জ শ্রোতাদের বলা হয়
  • রেডিও গ্রুপকে বোতাম বি-নির্বাচন করতে হবে । এটা আমার প্রশ্ন।

এখানে আমি যে প্রধান সমস্যাটির মুখোমুখি হচ্ছি তা হ'ল: আমি into োকাতে পারি না<Button>RadioGroup , কারণ এর গঠনটি এমন যে শিশুরা নির্বিচারে । অর্থাৎ মার্কআপ হতে পারে could

<RadioGroup>
    <Button title="A" />
    <Button title="B" />
</RadioGroup>

বা

<RadioGroup>
    <OtherThing title="A" />
    <OtherThing title="B" />
</RadioGroup>

আমি কয়েকটি জিনিস চেষ্টা করেছি।

প্রচেষ্টা করুন: ইন RadioGroupএর onChange হ্যান্ডলার সঠিক নয়:

React.Children.forEach( this.props.children, function( child ) {

    // Set the selected state of each child to be if the underlying <input>
    // value matches the child's value

    child.setState({ selected: child.props.value === e.target.value });

});

সমস্যা:

Invalid access to component property "setState" on exports at the top
level. See react-warning-descriptors . Use a static method
instead: <exports />.type.setState(...)

প্রচেষ্টা করুন: ইন RadioGroupএর onChange হ্যান্ডলার সঠিক নয়:

React.Children.forEach( this.props.children, function( child ) {

    child.props.selected = child.props.value === e.target.value;

});

সমস্যা: কিছুই হয় না, এমনকি আমি Buttonক্লাসকে একটি componentWillReceivePropsপদ্ধতিও দিই


চেষ্টা: আমি পিতামাতার কিছু নির্দিষ্ট অবস্থা বাচ্চাদের কাছে দেওয়ার চেষ্টা করেছি, তাই আমি কেবল পিতামাতার অবস্থা আপডেট করতে পারি এবং বাচ্চাদের স্বয়ংক্রিয়ভাবে প্রতিক্রিয়া জানাতে পারি। রেডিও গ্রুপের রেন্ডার ফাংশনে:

React.Children.forEach( this.props.children, function( item ) {
    this.transferPropsTo( item );
}, this);

সমস্যা:

Failed to make request: Error: Invariant Violation: exports: You can't call
transferPropsTo() on a component that you don't own, exports. This usually
means you are calling transferPropsTo() on a component passed in as props
or children.

খারাপ সমাধান # 1 : শিশুদের বৈশিষ্ট্যগুলি পাস করতে সক্ষম হতে রেন্ডার সময়ে ক্লোন করতে রিট্যাক্ট -অ্যাডনস.জেএস ক্লোনওথপপস পদ্ধতি ব্যবহার RadioGroupকরুন

খারাপ সমাধান # 2 : এইচটিএমএল / জেএসএক্সের চারপাশে একটি বিমূর্তি প্রয়োগ করুন যাতে সম্পত্তিগুলিতে গতিশীলভাবে পাস করতে পারি (আমাকে হত্যা করুন):

<RadioGroup items=[
    { type: Button, title: 'A' },
    { type: Button, title: 'B' }
]; />

এবং তারপরে RadioGroupগতিশীলভাবে এই বোতামগুলি তৈরি করুন।

এই প্রশ্নটি আমাকে সাহায্য করে না কারণ আমার বাচ্চাদের তারা কী তা জেনে রেন্ডার করা দরকার


যদি বাচ্চারা নির্বিচারে হতে পারে, তবে কীভাবে RadioGroupসম্ভবত এটি জানতে পারে যে এটির স্বেচ্ছাসেবী বাচ্চাদের কোনও ঘটনার প্রতিক্রিয়া জানাতে হবে? অগত্যা এটির শিশুদের সম্পর্কে কিছু জানতে হবে।
রস অ্যালেন

4
সাধারণভাবে, আপনি যদি নিজের মালিকানাধীন কোনও উপাদানটির বৈশিষ্ট্যগুলি পরিবর্তন করতে চান তবে এটির ক্লোন করুন React.addons.cloneWithPropsএবং আপনি যে নতুন প্রপাগুলি চান তা পাস করুন। propsঅপরিবর্তনীয়, তাই আপনি একটি নতুন হ্যাশ তৈরি করছেন, এটি বর্তমান প্রপসের সাথে একীভূত করছেন propsএবং সন্তানের উপাদানটির নতুন উদাহরণ হিসাবে নতুন হ্যাশটি প্রেরণ করছেন ।
রস অ্যালেন

উত্তর:


42

আপনি কেন বলছেন যে আমি নিশ্চিত cloneWithPropsহ'ল আমি নিশ্চিত নই তবে এটি ব্যবহার করে একটি কার্যকারী উদাহরণ is

var Hello = React.createClass({
    render: function() {
        return <div>Hello {this.props.name}</div>;
    }
});

var App = React.createClass({
    render: function() {
        return (
            <Group ref="buttonGroup">
                <Button key={1} name="Component A"/>
                <Button key={2} name="Component B"/>
                <Button key={3} name="Component C"/>
            </Group>
        );
    }
});

var Group = React.createClass({
    getInitialState: function() {
        return {
            selectedItem: null
        };
    },

    selectItem: function(item) {
        this.setState({
            selectedItem: item
        });
    },

    render: function() {
        var selectedKey = (this.state.selectedItem && this.state.selectedItem.props.key) || null;
        var children = this.props.children.map(function(item, i) {
            var isSelected = item.props.key === selectedKey;
            return React.addons.cloneWithProps(item, {
                isSelected: isSelected,
                selectItem: this.selectItem,
                key: item.props.key
            });
        }, this);

        return (
            <div>
                <strong>Selected:</strong> {this.state.selectedItem ? this.state.selectedItem.props.name : 'None'}
                <hr/>
                {children}
            </div>
        );
    }

});

var Button = React.createClass({
    handleClick: function() {
        this.props.selectItem(this);
    },

    render: function() {
        var selected = this.props.isSelected;
        return (
            <div
                onClick={this.handleClick}
                className={selected ? "selected" : ""}
            >
                {this.props.name} ({this.props.key}) {selected ? "<---" : ""}
            </div>
        );
    }

});


React.renderComponent(<App />, document.body);

এখানে একটি জেএসফিডেল এটি কার্যকরভাবে দেখায়।

সম্পাদনা : ডায়নামিক ট্যাব সামগ্রী সহ এখানে আরও একটি সম্পূর্ণ উদাহরণ: জেএসফিডাল


15
দ্রষ্টব্য: ক্লোনওথপপ্রসগুলি হ্রাস করা হয়েছে। পরিবর্তে React.cloneElement ব্যবহার করুন।
চেন-সু লিন

8
এটি D3 / জ্যাকুয়েরি কিছু করতে পারে এমন অবিশ্বাস্যরকম জটিল যে কেবল একটি: নির্বাচককে নয় this। প্রতিক্রিয়া ব্যবহার করা ছাড়া অন্য কোনও আসল সুবিধা রয়েছে কি?
পরিসংখ্যানগুলি শিখুন উদাহরণস্বরূপ

এফওয়াইআই .. এটি "প্যারেন্ট রাজ্য থেকে শিশুদের রাষ্ট্র আপডেট করা" নয়, এটি শিশুদের রাষ্ট্র আপডেট করার জন্য পিতা-মাতার রাষ্ট্র আপডেট করে। এখানে ক্রিয়াপদে একটি পার্থক্য রয়েছে। এই ক্ষেত্রে মানুষ বিভ্রান্ত।
স্কাল্লাজ

4
@ আইকনডোভারিটগুলি আপনি ঠিক, ভাইবোন সম্পর্ক, পিতা-মাতা এবং সন্তানের পিতা-মাতা কিছুটা জটিল। এটি জিনিসগুলি করার একটি মডুলার উপায়। তবে মনে রাখবেন জিনিসগুলি সম্পন্ন করার জন্য জিকুয়েরি একটি দ্রুত হ্যাক, রিঅ্যাক্টজেএস একটি অর্কেস্টেশন অনুযায়ী জিনিস রাখে।
স্কাল্লাজ

18

বোতামগুলি স্টেটলেস হওয়া উচিত। একটি বোতামের বৈশিষ্ট্যগুলি স্পষ্টভাবে আপডেট করার পরিবর্তে, কেবলমাত্র গোষ্ঠীর নিজস্ব রাষ্ট্র আপডেট করুন এবং পুনরায় রেন্ডার করুন। গ্রুপটির রেন্ডার পদ্ধতিটি তারপরে বাটনগুলি রেন্ডার করার সময় তার অবস্থার দিকে নজর দেওয়া উচিত এবং "সক্রিয়" (বা কিছু) কেবল সক্রিয় বোতামে পাস করবে।


প্রসারিত করতে, ক্লিক বা বা অন্যান্য সম্পর্কিত পদ্ধতিগুলি বোতামটি পিতামাতার কাছ থেকে সেট করা উচিত যাতে কোনও ক্রিয়াকলাপ প্যারেন্টে ফিরে রাষ্ট্রটি সেট করতে কল করে, বোতামের মধ্যেই নয়। এইভাবে বোতামটি পিতামাতার বর্তমান অবস্থার একটি রাষ্ট্রহীন প্রতিনিধিত্ব।
ডেভিড মর্টেনসন

6

হতে পারে আমার একটি অদ্ভুত সমাধান, তবে পর্যবেক্ষক প্যাটার্নটি ব্যবহার করবেন না কেন?

রেডিওগ্রুপ.জেএসএক্স

module.exports = React.createClass({
buttonSetters: [],
regSetter: function(v){
   buttonSetters.push(v);
},
handleChange: function(e) {
   // ...
   var name = e.target.name; //or name
   this.buttonSetters.forEach(function(v){
      if(v.name != name) v.setState(false);
   });
},
render: function() {
  return (
    <div>
      <Button title="A" regSetter={this.regSetter} onChange={handleChange}/>
      <Button title="B" regSetter={this.regSetter} onChange={handleChange} />
    </div>
  );
});

বাটন.জেএসএক্স

module.exports = React.createClass({

    onChange: function( e ) {
        // How to modify children properties here???
    },
    componentDidMount: function() {
         this.props.regSetter({name:this.props.title,setState:this.setState});
    },
    onChange:function() {
         this.props.onChange();
    },
    render: function() {
        return (<div onChange={this.onChange}>
            <input element .../>
        </div>);
    }

});

আপনার অন্য কিছু প্রয়োজন হতে পারে তবে আমি এটি খুব শক্তিশালী পেয়েছি,

আমি সত্যই বাইরের একটি মডেল ব্যবহার করতে পছন্দ করি যা বিভিন্ন কাজের জন্য পর্যবেক্ষক নিবন্ধের পদ্ধতি সরবরাহ করে


কোনও নোডের জন্য স্পষ্টভাবে অন্য নোডে সেটস্টেট কল করা কি খারাপ ফর্ম নয়? আরও কী প্রতিক্রিয়াশীল উপায় হ'ল রেডিওগ্রুপে কিছু স্টেট আপডেট করা, আরেকটি রেন্ডার পাসকে ট্রিগার করা যাতে আপনি বংশধরের প্রপসগুলি প্রয়োজনীয় হিসাবে আপডেট করতে পারেন?
কিউস

4
স্পষ্টভাবে? না, পর্যবেক্ষক কেবল একটি কলব্যাক কল করেন, এটি সেটস্টেট হিসাবে ঘটেছিল, তবে বাস্তবে আমি এটি.সেটস্টেট.বাইন্ড (এটি) নির্দিষ্ট করতে পারতাম এবং তাই কেবল নিজের কাছে আবদ্ধ থাকি। ঠিক আছে, যদি আমাকে সত্যবাদিতা করতে হয় তবে আমার উচিত ছিল কোনও স্থানীয় ফাংশন / পদ্ধতি যা সেটস্টেটকে কল করে পর্যবেক্ষকের কাছে এটি নিবন্ধিত করা উচিত
ড্যানিয়েল ক্রুসিয়ানি

4
আমি কি এই ভুলটি পড়ছি, বা আপনার কাছে একই নামে দুটি ক্ষেত্র একই উদ্দেশ্যে রয়েছে Button.jsx?
জনক

বাটন.জেএসএক্স অন্তর্ভুক্ত onChange()এবংonChange(e)
জোশ

প্রথমটি মুছে ফেলুন, এটি প্রশ্নটি (প্রথম প্রশ্ন) থেকে কেটে পেস্ট করুন। এটি বিন্দু নয়, এটি একটি কার্য কোড নয়, এটিও হবে না।
ড্যানিয়েল ক্রুসিয়ানি

0

এমন একটি বস্তু তৈরি করুন যা পিতা বা মাতা এবং সন্তানের মধ্যে মধ্যস্থতা হিসাবে কাজ করে। এই অবজেক্টটিতে পিতা বা মাতা এবং সন্তানের উভয়ই ফাংশন উল্লেখ রয়েছে। এরপরে অবজেক্টটি সন্তানের কাছে পিতামাতার কাছ থেকে প্রস্তাব হিসাবে পাস করা হয়। কোড উদাহরণ এখানে:

https://stackoverflow.com/a/61674406/753632

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