বিক্রিয়া জেএস: সন্তানের উপাদানগুলির মধ্যে পিতামাতার উপর সেটস্টেট


91

সন্তানের উপাদান থেকে পিতামাতার উপর সেটস্টেট করার জন্য প্রস্তাবিত প্যাটার্নটি কী।

var Todos = React.createClass({
  getInitialState: function() {
    return {
      todos: [
        "I am done",
        "I am not done"
      ]
    }
  },

  render: function() {
    var todos = this.state.todos.map(function(todo) {
      return <div>{todo}</div>;
    });

    return <div>
      <h3>Todo(s)</h3>
      {todos}
      <TodoForm />
    </div>;
  }
});

var TodoForm = React.createClass({
  getInitialState: function() {
    return {
      todoInput: ""
    }
  },

  handleOnChange: function(e) {
    e.preventDefault();
    this.setState({todoInput: e.target.value});
  },

  handleClick: function(e) {
    e.preventDefault();
    //add the new todo item
  },

  render: function() {
    return <div>
      <br />
      <input type="text" value={this.state.todoInput} onChange={this.handleOnChange} />
      <button onClick={this.handleClick}>Add Todo</button>
    </div>;
  }
});

React.render(<Todos />, document.body)

আমার কাছে টুডো আইটেমগুলির একটি অ্যারে রয়েছে যা পিতামাতার রাজ্যে বজায় থাকে। আমি পিতামাতার রাজ্যে অ্যাক্সেস করতে চাই এবং TodoFormএর handleClickউপাদান থেকে একটি নতুন টুডো আইটেম যুক্ত করতে চাই । আমার ধারণা পিতামাতার উপর একটি সেটস্টেট করা, যা সদ্য যুক্ত হওয়া টুডো আইটেমটি রেন্ডার করবে।



এখানে কেবল স্প্যাম হবে ... npmjs.com/package/react-event-observer
jujyyangasli

আমি ত্রুটি পাচ্ছিsetState(...): Can only update a mounted or mounting component. This usually means you called setState() on an unmounted component. This is a no-op. Please check the code for the MyModal component.
ম্যাট

আমি একই ত্রুটিটি পাচ্ছি যা আমি কোনও আনমাউন্টযুক্ত উপাদানগুলিতে সেট স্টেট করতে পারি না। এটির জন্য কি কোনও পরিকল্পনা ছিল?
কেভিন বার্টন

উত্তর:


82

আপনার পিতামাতায়, আপনি এমন একটি ফাংশন তৈরি করতে পারেন addTodoItemযা প্রয়োজনীয় সেটস্টেটটি করবে এবং তারপরে সেই ফাংশনটি সন্তানের উপাদানগুলিতে প্রপস হিসাবে পাস করবে।

var Todos = React.createClass({

  ...

  addTodoItem: function(todoItem) {
    this.setState(({ todos }) => ({ todos: { ...todos, todoItem } }));
  },

  render: function() {

    ...

    return <div>
      <h3>Todo(s)</h3>
      {todos}
      <TodoForm addTodoItem={this.addTodoItem} />
    </div>
  }
});

var TodoForm = React.createClass({
  handleClick: function(e) {
    e.preventDefault();
    this.props.addTodoItem(this.state.todoInput);
    this.setState({todoInput: ""});
  },

  ...

});

আপনি addTodoItemটডোফর্মের হ্যান্ডেল ক্লিকে অনুরোধ করতে পারেন । এটি প্যারেন্টে একটি সেটস্টেট করবে যা সদ্য যুক্ত হওয়া টুডো আইটেমটি রেন্ডার করবে। আশা করি ধারণাটি পেয়ে যাবেন।

ফিডল এখানে।


6
কি <<মধ্যে অপারেটর this.state.todos << todoItem;এখানে করছেন?
গ্যাব্রিয়েল গ্যারেট

@ জাভ্রা লিটল রুবি বিভ্রান্তি ঘটছে আমার অনুমান
আজিয়াম

7
this.stateসরাসরি রূপান্তরিত করা খারাপ অভ্যাস । ফাংশনাল সেটস্টেট ব্যবহার করা আরও ভাল। reactjs.org/docs/react-component.html#setstate
Rohmer

4
ভাঙা ভাঙা
হান্টার নেলসন

4
কীভাবে এই (আপডেট করা) সমাধানটি প্রতিক্রিয়া হুক ব্যবহার করে প্রয়োগ করা হবে?
ইকো

11

এগুলি সবগুলিই মূলত সঠিক, আমি কেবল ভেবেছিলাম নতুন (ইশ) অফিসিয়াল প্রতিক্রিয়ার ডকুমেন্টেশনের দিকে ইঙ্গিত করব যা মূলত সুপারিশ করে: -

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

Https://reactjs.org/docs/lift-state-up.html দেখুন । পৃষ্ঠাটি উদাহরণের মাধ্যমেও কাজ করে।


8

আপনি প্যারেন্ট উপাদানগুলিতে একটি অ্যাডটোডো ফাংশন তৈরি করতে পারেন, এটিকে সেই প্রসঙ্গে বেঁধে রাখতে পারেন, এটি সন্তানের উপাদানটিতে প্রেরণ করতে এবং সেখান থেকে কল করতে পারেন।

// in Todos
addTodo: function(newTodo) {
    // add todo
}

তারপরে, টডোস.রেেন্ডারে আপনি তা করবেন

<TodoForm addToDo={this.addTodo.bind(this)} />

এর সাথে টোডোফোমে কল করুন

this.props.addToDo(newTodo);

এটি এত দরকারী ছিল। bind(this)ক্রিয়াকলাপটি পাস করার সময় না করে এটি ত্রুটি ছুঁড়ে দিয়েছিল এরকম কোনও ফাংশন নেই this.setState is not a function
প্রতাপ

7

যারা প্রতিক্রিয়া হুক দিয়ে রাষ্ট্র বজায় রাখছেন useState, আমি উপরের পরামর্শগুলি নীচে একটি ডেমো স্লাইডার অ্যাপ্লিকেশনটি রূপান্তর করেছি suggestions ডেমো অ্যাপ্লিকেশনে, শিশু স্লাইডার উপাদানটি পিতামাতার অবস্থা বজায় রাখে।

ডেমো useEffectহুক ব্যবহার করে । (এবং আরও কম গুরুত্বপূর্ণ, useRefহুক)

import React, { useState, useEffect, useCallback, useRef } from "react";

//the parent react component
function Parent() {

  // the parentState will be set by its child slider component
  const [parentState, setParentState] = useState(0);

  // make wrapper function to give child
  const wrapperSetParentState = useCallback(val => {
    setParentState(val);
  }, [setParentState]);

  return (
    <div style={{ margin: 30 }}>
      <Child
        parentState={parentState}
        parentStateSetter={wrapperSetParentState}
      />
      <div>Parent State: {parentState}</div>
    </div>
  );
};

//the child react component
function Child({parentStateSetter}) {
  const childRef = useRef();
  const [childState, setChildState] = useState(0);

  useEffect(() => {
    parentStateSetter(childState);
  }, [parentStateSetter, childState]);

  const onSliderChangeHandler = e => {
  //pass slider's event value to child's state
    setChildState(e.target.value);
  };

  return (
    <div>
      <input
        type="range"
        min="1"
        max="255"
        value={childState}
        ref={childRef}
        onChange={onSliderChangeHandler}
      ></input>
    </div>
  );
};

export default Parent;

আপনি এই অ্যাপ্লিকেশনটিকে তৈরি-প্রতিক্রিয়া-অ্যাপ্লিকেশন সহ ব্যবহার করতে পারেন এবং অ্যাপ.জেজে সমস্ত কোডকে উপরের কোড দিয়ে প্রতিস্থাপন করতে পারেন।
নিকোহিট

হাই, আমি প্রতিক্রিয়া জানাতে নতুন এবং ভাবছিলাম: এটি ব্যবহার করা প্রয়োজন useEffect? আমাদের পিতামাতা ও শিশু উভয় অবস্থাতেই ডেটা সংরক্ষণ করা দরকার কেন?
538 রোমো

4
উদাহরণগুলি অভিভাবক এবং সন্তানের উভয় ক্ষেত্রেই আমাদের কেন ডেটা সঞ্চয় করতে হবে তা দেখানোর উদ্দেশ্যে নয়- বেশিরভাগ সময় আপনার প্রয়োজন হয় না। তবে, আপনি যদি নিজেকে এমন পরিস্থিতিতে আবিষ্কার করেন যে সন্তানের পিতা-মাতার অবস্থা নির্ধারণ করা উচিত তবে আপনি এটি এটি করতে পারেন। যদি আপনি চাইল্ডস্টেটের পরিবর্তনের একটি প্রভাব হিসাবে পিতৃত্বের রাজ্যটি সেট করতে চান তবে ইউজএফেক্টটি প্রয়োজনীয়।
নিকোহিট

3
parentSetState={(obj) => { this.setState(obj) }}

4
যদিও এই কোডটি প্রশ্নের উত্তর দিতে পারে, কীভাবে এবং / বা কেন এটি সমস্যার সমাধান করে তা সম্পর্কিত অতিরিক্ত প্রসঙ্গ সরবরাহ করলে উত্তরের দীর্ঘমেয়াদী মান উন্নত হবে।
নিক 3500

2

সন্তানের উপাদান থেকে অভিভাবক উপাদানগুলিতে যুক্তিগুলি পাস করার জন্য আমি নিম্নলিখিত কার্যকরী এবং সহজ সমাধানটি পেয়েছি:

//ChildExt component
class ChildExt extends React.Component {
    render() {
        var handleForUpdate =   this.props.handleForUpdate;
        return (<div><button onClick={() => handleForUpdate('someNewVar')}>Push me</button></div>
        )
    }
}

//Parent component
class ParentExt extends React.Component {   
    constructor(props) {
        super(props);
        var handleForUpdate = this.handleForUpdate.bind(this);
    }
    handleForUpdate(someArg){
            alert('We pass argument from Child to Parent: \n' + someArg);   
    }

    render() {
        var handleForUpdate =   this.handleForUpdate;    
        return (<div>
                    <ChildExt handleForUpdate = {handleForUpdate.bind(this)} /></div>)
    }
}

if(document.querySelector("#demo")){
    ReactDOM.render(
        <ParentExt />,
        document.querySelector("#demo")
    );
}

JSFIDDLE দেখুন


0

আপনি যদি অভিভাবক হিসাবে কোনও শ্রেণীর উপাদান নিয়ে কাজ করছেন তবে একটি বাচ্চার কাছে সেটস্টেট পাস করার একটি খুব সহজ উপায় হ'ল এটি একটি তীর ফাংশনের মধ্যে দিয়ে। এটি কোনও উত্তোলিত পরিবেশ সেট করে যেমন কাজ করে যা চারপাশে চলে যেতে পারে:

class ClassComponent ... {

    modifyState = () =>{
        this.setState({...})   
    }
    render(){
          return <><ChildComponent parentStateModifier={modifyState} /></>
    }
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.