จะอัพเดทสถานะของผู้ปกครองในการตอบสนองได้อย่างไร?


351

โครงสร้างของฉันมีลักษณะดังนี้:

Component 1  

 - |- Component 2


 - - |- Component 4


 - - -  |- Component 5  

Component 3

องค์ประกอบที่ 3 ควรแสดงข้อมูลบางอย่างขึ้นอยู่กับสถานะขององค์ประกอบที่ 5 เนื่องจากอุปกรณ์ประกอบฉากไม่มีการเปลี่ยนแปลงฉันจึงไม่สามารถบันทึกสถานะไว้ในองค์ประกอบที่ 1 และส่งต่อได้ใช่ไหม และใช่ฉันได้อ่านเกี่ยวกับการเปลี่ยนสี แต่ไม่ต้องการใช้ ฉันหวังว่ามันเป็นไปได้ที่จะแก้มันด้วยการตอบสนอง ฉันผิดหรือเปล่า?


20
ง่ายสุด ๆ : ผ่าน parent-setState-Function ผ่านคุณสมบัติไปยัง child-component: <MyChildComponent setState = {p => {this.setState (p)}} /> ในองค์ประกอบเด็กเรียกมันผ่าน this.props setState ({myObj, ... });
Marcel Ennix

@MarcelEnnix ความคิดเห็นของคุณประหยัดเวลาของฉัน ขอบคุณ
Dinith Minura

<MyChildComponent setState={(s,c)=>{this.setState(s, c)}} />ถ้าคุณจะใช้แฮ็คนี้คุณต้องแน่ใจว่าคุณรองรับการโทรกลับ
Barkermn01

4
ผ่านการเรียกกลับเพื่อกำหนดสถานะของผู้ปกครองเป็นวิธีปฏิบัติที่ไม่ดีจริง ๆ ที่อาจนำไปสู่ปัญหาการบำรุง มันแยก encapsulation และทำให้ส่วนประกอบ 2 4 และ 5 รวมกันเป็น 1 อย่างแน่นหนากับ 1 หากเดินไปตามเส้นทางนี้คุณจะไม่สามารถนำองค์ประกอบย่อยเหล่านี้ไปใช้ที่อื่นได้อีก จะเป็นการดีกว่าที่คุณมีอุปกรณ์ประกอบฉากที่เฉพาะเจาะจงเพื่อให้องค์ประกอบของเด็กสามารถเรียกเหตุการณ์เมื่อใดก็ตามที่มีอะไรเกิดขึ้นจากนั้นองค์ประกอบหลักจะจัดการกับเหตุการณ์นั้นอย่างถูกต้อง
Pato Loco

@ MarcelEnnix ทำไมวงเล็บปีกกาประมาณthis.setState(p)? ฉันพยายามโดยไม่มีพวกเขาและดูเหมือนว่าจะทำงาน (ฉันใหม่มากที่จะตอบสนอง)
Biganon

คำตอบ:


679

สำหรับการสื่อสารระหว่างผู้ปกครองเด็กคุณควรผ่านฟังก์ชั่นการตั้งค่าสถานะจากผู้ปกครองไปยังเด็กเช่นนี้

class Parent extends React.Component {
  constructor(props) {
    super(props)

    this.handler = this.handler.bind(this)
  }

  handler() {
    this.setState({
      someVar: 'some value'
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {this.props.handler}/ >
  }
}

วิธีนี้เด็กสามารถอัปเดตสถานะของผู้ปกครองด้วยการเรียกใช้ฟังก์ชันที่ส่งผ่านด้วยอุปกรณ์ประกอบฉาก

แต่คุณจะต้องคิดใหม่โครงสร้างของส่วนประกอบเพราะฉันเข้าใจว่าส่วนประกอบ 5 และ 3 ไม่เกี่ยวข้องกัน

ทางออกหนึ่งที่เป็นไปได้คือการห่อไว้ในส่วนประกอบระดับที่สูงขึ้นซึ่งจะมีสถานะขององค์ประกอบทั้ง 1 และ 3 ส่วนประกอบนี้จะตั้งค่าสถานะระดับล่างผ่านอุปกรณ์ประกอบฉาก


6
ทำไมคุณต้องการ this.handler = this.handler.bind (นี่) และไม่ใช่แค่ฟังก์ชันตัวจัดการที่ตั้งค่าสถานะ
chemook78

35
@ chemook78 ในวิธีการเรียน ES6 React ไม่ผูกกับคลาสโดยอัตโนมัติ ดังนั้นถ้าเราไม่เพิ่มthis.handler = this.handler.bind(this)ในตัวสร้างthisภายในhandlerฟังก์ชันจะอ้างอิงการปิดฟังก์ชันไม่ใช่คลาส หากไม่ต้องการผูกฟังก์ชั่นทั้งหมดของคุณในตัวสร้างมีสองวิธีที่จะจัดการกับสิ่งนี้โดยใช้ฟังก์ชั่นลูกศร คุณสามารถเขียนตัวจัดการคลิกเป็นonClick={()=> this.setState(...)}หรือคุณสามารถใช้คุณสมบัติเริ่มต้นพร้อมกับฟังก์ชั่นลูกศรตามที่อธิบายไว้ที่นี่babeljs.io/blog/2015/06/07/react-on-es6-plusภายใต้ "ฟังก์ชั่น Arrow"
Ivan

1
นี่คือตัวอย่างของการกระทำนี้: plnkr.co/edit/tGWecotmktae8zjS5yEr?p=preview
Tamb

5
นั่นเป็นเหตุผลว่าทำไม e.preventDefault และนั่นต้อง jquery?
Vincent Buscarello

1
คำถามด่วนสิ่งนี้ไม่อนุญาตให้มีการกำหนดรัฐท้องถิ่นภายในเด็กหรือไม่?
ThisGuyCantEven

50

ฉันพบวิธีแก้ปัญหาการทำงานต่อไปนี้เพื่อส่งต่ออาร์กิวเมนต์ฟังก์ชัน onClick จากชายด์ไปยังคอมโพเนนต์พาเรนต์:

รุ่นที่มีการส่งเมธอด ()

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate  =   this.props.handleToUpdate;
        return (<div><button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component {

    constructor(props) {
        super(props);
        var handleToUpdate  = this.handleToUpdate.bind(this);
        var arg1 = '';
    }

    handleToUpdate(someArg){
            alert('We pass argument from Child to Parent: ' + someArg);
            this.setState({arg1:someArg});
    }

    render() {
        var handleToUpdate  =   this.handleToUpdate;

        return (<div>
                    <ChildB handleToUpdate = {handleToUpdate.bind(this)} /></div>)
    }
}

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

ดูที่ JSFIDDLE

เวอร์ชันที่ส่งผ่านฟังก์ชั่นลูกศร

//ChildB component
class ChildB extends React.Component {

    render() {

        var handleToUpdate  =   this.props.handleToUpdate;
        return (<div>
          <button onClick={() => handleToUpdate('someVar')}>
            Push me
          </button>
        </div>)
    }
}

//ParentA component
class ParentA extends React.Component { 
    constructor(props) {
        super(props);
    }

    handleToUpdate = (someArg) => {
            alert('We pass argument from Child to Parent: ' + someArg);
    }

    render() {
        return (<div>
            <ChildB handleToUpdate = {this.handleToUpdate} /></div>)
    }
}

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

ดูที่ JSFIDDLE


อันนี้ดี! คุณช่วยอธิบายชิ้นนี้ได้: <ChildB handleToUpdate = {handleToUpdate.bind(this)} />ทำไมต้องผูกอีกครั้ง?
ชาวเดนมาร์ก

@Dane - คุณต้องผูกบริบทของสิ่งนี้ให้เป็นพ่อแม่เพื่อที่ว่าเมื่อthisถูกเรียกข้างในเด็กthisหมายถึงสถานะของผู้ปกครองไม่ใช่ของเด็ก นี่เป็นการปิดที่ดีที่สุด!
Casey

@Casey แต่เราไม่ได้ทำอย่างนั้นในนวกรรมิก? และยังไม่เพียงพอหรือ
Dane

คุณพูดถูก! ฉันคิดถึงสิ่งนั้น ใช่ถ้าคุณทำมันในคอนสตรัคเตอร์คุณก็ยินดีที่จะไป!
Casey

คุณเป็นเพื่อนในตำนาน! สิ่งนี้จะทำให้ส่วนประกอบที่มีอยู่ในตัวเป็นของตัวเองโดยไม่ต้องถูกบังคับให้สร้างส่วนประกอบหลักเพื่อจัดการกับการแลกเปลี่ยนสถานะ
adamj

13

ฉันอยากจะขอบคุณคำตอบที่ได้รับการโหวตมากที่สุดที่ให้ความคิดเกี่ยวกับปัญหาของฉันเองโดยพื้นฐานแล้วการเปลี่ยนแปลงของมันด้วยฟังก์ชั่นลูกศรและผ่านพารามิเตอร์จากองค์ประกอบของเด็ก:

 class Parent extends React.Component {
  constructor(props) {
    super(props)
    // without bind, replaced by arrow func below
  }

  handler = (val) => {
    this.setState({
      someVar: val
    })
  }

  render() {
    return <Child handler = {this.handler} />
  }
}

class Child extends React.Component {
  render() {
    return <Button onClick = {() => this.props.handler('the passing value')}/ >
  }
}

หวังว่าจะช่วยใครซักคน


อะไรเป็นพิเศษเกี่ยวกับฟังก์ชั่นลูกศรผ่านสายตรง
Ashish Kamble

@AshishKamble thisฟังก์ชั่นลูกศรหมายถึงบริบทของผู้ปกครอง (เช่นParentชั้นเรียน)
CPHPython

นี่คือคำตอบที่ซ้ำกัน คุณสามารถเพิ่มความคิดเห็นในคำตอบที่ยอมรับและพูดถึงเกี่ยวกับคุณลักษณะทดลองนี้เพื่อใช้ฟังก์ชั่นลูกศรในชั้นเรียน
Arashsoft

10

ฉันชอบคำตอบเกี่ยวกับฟังก์ชั่นการส่งผ่านซึ่งเป็นเทคนิคที่มีประโยชน์มาก

เมื่อพลิกด้านคุณยังสามารถบรรลุนี้โดยใช้ผับ / ย่อยหรือใช้ตัวแปรมอบหมายเป็นมูกเลือดไม่ ทฤษฎีง่ายมากมีส่วนประกอบ 5 ส่งข้อความซึ่งองค์ประกอบ 3 กำลังฟังอยู่ องค์ประกอบที่ 3 จะอัพเดทสถานะของมันซึ่งทำให้เกิดการแสดงผลซ้ำ สิ่งนี้ต้องมีส่วนประกอบที่เป็นของรัฐซึ่งขึ้นอยู่กับมุมมองของคุณอาจจะใช่หรือไม่ใช่ต่อต้านรูปแบบก็ได้ ฉันต่อสู้กับพวกเขาเป็นการส่วนตัวและต้องการที่จะมีอย่างอื่นที่กำลังรอรับการเปลี่ยนแปลงและเปลี่ยนสถานะจากบนลงล่าง (Redux ทำเช่นนี้ แต่เพิ่มคำศัพท์เพิ่มเติม)

import { Dispatcher } from flux
import { Component } from React

const dispatcher = new Dispatcher()

// Component 3
// Some methods, such as constructor, omitted for brevity
class StatefulParent extends Component {
  state = {
    text: 'foo'
  } 

  componentDidMount() {
    dispatcher.register( dispatch => {
      if ( dispatch.type === 'change' ) {
        this.setState({ text: 'bar' })
      }
    }
  }

  render() {
    return <h1>{ this.state.text }</h1>
  }
}

// Click handler
const onClick = event => {
  dispatcher.dispatch({
    type: 'change'
  })
}

// Component 5 in your example
const StatelessChild = props => {
  return <button onClick={ onClick }>Click me</button> 
}

บันเดิลดิสแพตเชอร์ที่มีฟลักซ์นั้นง่ายมากมันเพียงแค่ลงทะเบียนการโทรกลับและเรียกใช้เมื่อการจัดส่งใด ๆ เกิดขึ้นผ่านเนื้อหาในการจัดส่ง (ในตัวอย่าง terse ด้านบนไม่มีpayloadการส่งเพียง ID ข้อความ) คุณสามารถปรับให้เหมาะกับ pub / sub แบบดั้งเดิม (เช่นใช้ EventEmitter จากเหตุการณ์หรือรุ่นอื่น ๆ ) ได้อย่างง่ายดายหากคุณเข้าใจได้ง่ายกว่า


ส่วนประกอบ Reacts ของฉัน "ทำงาน" ในเบราว์เซอร์เหมือนในแบบฝึกหัดอย่างเป็นทางการ ( facebook.github.io/react/docs/tutorial.html ) ฉันพยายามที่จะรวม Flux กับ browserify แต่เบราว์เซอร์บอกว่าไม่พบ Dispatcher :(
wklm

2
ไวยากรณ์ที่ฉันใช้คือไวยากรณ์โมดูล ES2016 ซึ่งต้องการการแปลงสัญญาณ (ฉันใช้Babelแต่มีคนอื่น ๆ การแปลงbabelifyสามารถใช้กับ browserify) มัน transpiles ไปvar Dispatcher = require( 'flux' ).Dispatcher
แมตต์สไตล์

8

ฉันพบวิธีแก้ปัญหาการทำงานต่อไปนี้เพื่อส่งต่ออาร์กิวเมนต์ฟังก์ชัน onClick จากชายด์ไปยังคอมโพเนนต์พาเรนต์ที่มีพารามิเตอร์:

ระดับผู้ปกครอง:

class Parent extends React.Component {
constructor(props) {
    super(props)

    // Bind the this context to the handler function
    this.handler = this.handler.bind(this);

    // Set some state
    this.state = {
        messageShown: false
    };
}

// This method will be sent to the child component
handler(param1) {
console.log(param1);
    this.setState({
        messageShown: true
    });
}

// Render the child component and set the action property with the handler as value
render() {
    return <Child action={this.handler} />
}}

ชั้นเรียนเด็ก:

class Child extends React.Component {
render() {
    return (
        <div>
            {/* The button will execute the handler function set by the parent component */}
            <Button onClick={this.props.action.bind(this,param1)} />
        </div>
    )
} }

2
ทุกคนสามารถบอกได้ว่าเป็นวิธีการแก้ปัญหาที่ยอมรับได้หรือไม่ (สนใจโดยเฉพาะอย่างยิ่งในการส่งพารามิเตอร์ตามที่แนะนำ)
ilans

param1เป็นเพียงการแสดงบนคอนโซลไม่ได้รับมอบหมายมันมักจะได้รับมอบหมายtrue
Ashish Kamble

ฉันไม่สามารถพูดคุยกับคุณภาพของการแก้ปัญหา แต่สิ่งนี้ผ่าน param ให้ฉันได้สำเร็จ
James

6

เมื่อคุณเคยต้องใช้การติดต่อสื่อสารระหว่างเด็กไปยังผู้ปกครองที่ลงในระดับใดแล้วมันจะดีกว่าที่จะทำให้การใช้งานของ บริบท ในองค์ประกอบหลักกำหนดบริบทที่สามารถเรียกใช้โดยเด็กเช่น

ในคอมโพเนนต์หลักในคอมโพเนนต์เคสของคุณ 3

static childContextTypes = {
        parentMethod: React.PropTypes.func.isRequired
      };

       getChildContext() {
        return {
          parentMethod: (parameter_from_child) => this.parentMethod(parameter_from_child)
        };
      }

parentMethod(parameter_from_child){
// update the state with parameter_from_child
}

ตอนนี้อยู่ในองค์ประกอบลูก (องค์ประกอบ 5 ในกรณีของคุณ) เพียงแค่บอกส่วนประกอบนี้ว่าต้องการใช้บริบทของพาเรนต์

 static contextTypes = {
       parentMethod: React.PropTypes.func.isRequired
     };
render(){
    return(
      <TouchableHighlight
        onPress={() =>this.context.parentMethod(new_state_value)}
         underlayColor='gray' >   

            <Text> update state in parent component </Text>              

      </TouchableHighlight>
)}

คุณสามารถค้นหาโครงการสาธิตได้ที่repo


ฉันไม่สามารถเข้าใจคำตอบนี้คุณช่วยอธิบายเพิ่มเติมเกี่ยวกับมันได้ไหม
Ashish Kamble

5

ดูเหมือนว่าเราสามารถส่งผ่านข้อมูลจากพาเรนต์ไปยังเด็กได้เท่านั้นเนื่องจากการตอบสนองจะส่งเสริมการไหลของข้อมูลแบบทิศทางเดียว แต่เพื่อให้พาเรนต์อัปเดตตัวเองเมื่อเกิดอะไรขึ้นใน "องค์ประกอบลูก" ของมัน

เราผ่านฟังก์ชั่นที่กำหนดในผู้ปกครองไปยังเด็กเป็น "อุปกรณ์ประกอบฉาก" และเรียกใช้ฟังก์ชั่นนั้นจากเด็กที่เรียกมันในองค์ประกอบผู้ปกครอง


class Parent extends React.Component {
  handler = (Value_Passed_From_SubChild) => {
    console.log("Parent got triggered when a grandchild button was clicked");
    console.log("Parent->Child->SubChild");
    console.log(Value_Passed_From_SubChild);
  }
  render() {
    return <Child handler = {this.handler} />
  }
}
class Child extends React.Component {
  render() {
    return <SubChild handler = {this.props.handler}/ >
  }
}
class SubChild extends React.Component { 
  constructor(props){
   super(props);
   this.state = {
      somethingImp : [1,2,3,4]
   }
  }
  render() {
     return <button onClick = {this.props.handler(this.state.somethingImp)}>Clickme<button/>
  }
}
React.render(<Parent />,document.getElementById('app'));

 HTML
 ----
 <div id="app"></div>

ในตัวอย่างนี้เราสามารถสร้าง data pass จาก SubChild -> Child -> Parent โดยส่งผ่านฟังก์ชันไปยัง Child โดยตรง


4

ฉันใช้คำตอบที่ได้รับคะแนนสูงสุดจากหน้านี้หลายครั้ง แต่ในขณะที่การเรียนรู้ตอบสนองฉันพบวิธีที่ดีกว่าในการทำเช่นนั้นโดยไม่มีการผูกและไม่มีฟังก์ชั่นอินไลน์ภายในอุปกรณ์ประกอบฉาก

เพียงดูที่นี่:

class Parent extends React.Component {

  constructor() {
    super();
    this.state={
      someVar: value
    }
  }

  handleChange=(someValue)=>{
    this.setState({someVar: someValue})
  }

  render() {
    return <Child handler={this.handleChange} />
  }

}

export const Child = ({handler}) => {
  return <Button onClick={handler} />
}

กุญแจอยู่ในฟังก์ชั่นลูกศร:

handleChange=(someValue)=>{
  this.setState({someVar: someValue})
}

คุณสามารถอ่านเพิ่มเติมที่นี่ หวังว่านี่จะเป็นประโยชน์สำหรับใครบางคน =)


ทำให้ฉันมีเหตุผลมากขึ้น ขอบคุณ!
Brett Rowberry

3

- เราสามารถสร้าง ParentComponent และด้วย handleInputChange วิธีการปรับปรุงสถานะ ParentComponent นำเข้า ChildComponent และเราส่งสองอุปกรณ์ประกอบฉากจากผู้ปกครองไปยังองค์ประกอบของเด็กเช่นฟังก์ชั่น.handleInputChangeและนับ

import React, { Component } from 'react';
import ChildComponent from './ChildComponent';

class ParentComponent extends Component {
  constructor(props) {
    super(props);
    this.handleInputChange = this.handleInputChange.bind(this);
    this.state = {
      count: '',
    };
  }

  handleInputChange(e) {
    const { value, name } = e.target;
    this.setState({ [name]: value });
  }

  render() {
    const { count } = this.state;
    return (
      <ChildComponent count={count} handleInputChange={this.handleInputChange} />
    );
  }
}
  • ตอนนี้เราสร้างไฟล์ ChildComponent และบันทึกเป็น ChildComponent.jsx ส่วนประกอบนี้เป็นไร้สัญชาติเนื่องจากองค์ประกอบย่อยไม่มีสถานะ เราใช้ไลบรารีประเภท prop สำหรับการตรวจสอบประเภทอุปกรณ์ประกอบฉาก

    import React from 'react';
    import { func, number } from 'prop-types';
    
    const ChildComponent = ({ handleInputChange, count }) => (
      <input onChange={handleInputChange} value={count} name="count" />
    );
    
    ChildComponent.propTypes = {
      count: number,
      handleInputChange: func.isRequired,
    };
    
    ChildComponent.defaultProps = {
      count: 0,
    };
    
    export default ChildComponent;

มันจะทำงานอย่างไรเมื่อเด็กมีลูกที่ส่งผลกระทบต่อเสาของผู้ปกครอง?
Bobort

3

หากสถานการณ์เดียวกันนี้ไม่แพร่กระจายไปทุกหนทุกแห่งคุณสามารถใช้บริบทของ React โดยเฉพาะถ้าคุณไม่ต้องการแนะนำค่าใช้จ่ายทั้งหมดที่ห้องสมุดการจัดการสถานะแนะนำ นอกจากนี้ยังง่ายต่อการเรียนรู้ แต่ระวังคุณอาจใช้มากเกินไปและเริ่มเขียนรหัสที่ไม่ดี โดยทั่วไปคุณจะกำหนดส่วนประกอบของ Container (ที่จะเก็บและรักษาส่วนนั้นไว้ให้คุณ) ทำให้ส่วนประกอบทั้งหมดสนใจในการเขียน / อ่านข้อมูลชิ้นส่วนลูก (ไม่จำเป็นต้องเป็นลูกโดยตรง)

https://reactjs.org/docs/context.html

คุณสามารถใช้ React ธรรมดาได้อย่างถูกต้องแทน

<Component5 onSomethingHappenedIn5={this.props.doSomethingAbout5} />

ผ่าน doSomethingAbout5 จนถึง Component 1

    <Component1>
        <Component2 onSomethingHappenedIn5={somethingAbout5 => this.setState({somethingAbout5})}/>
        <Component5 propThatDependsOn5={this.state.somethingAbout5}/>
    <Component1/>

หากนี่เป็นปัญหาทั่วไปคุณควรเริ่มคิดที่จะย้ายสถานะทั้งหมดของแอปพลิเคชันไปยังที่อื่น คุณมีตัวเลือกไม่กี่ตัวที่พบบ่อยที่สุดคือ:

https://redux.js.org/

https://facebook.github.io/flux/

โดยพื้นฐานแล้วแทนที่จะจัดการสถานะแอปพลิเคชันในส่วนประกอบของคุณคุณจะส่งคำสั่งเมื่อมีบางอย่างเกิดขึ้นเพื่อให้ได้รับการอัพเดต ส่วนประกอบดึงสถานะจากคอนเทนเนอร์นี้เช่นกันดังนั้นข้อมูลทั้งหมดจึงรวมศูนย์ นี่ไม่ได้หมายความว่าไม่สามารถใช้สถานะท้องถิ่นได้อีก แต่นั่นเป็นหัวข้อขั้นสูงกว่า


2

ดังนั้นหากคุณต้องการอัพเดทองค์ประกอบหลัก

 class ParentComponent extends React.Component {
        constructor(props){
            super(props);
            this.state = {
               page:0
            }
        }

        handler(val){
            console.log(val) // 1
        }

        render(){
          return (
              <ChildComponent onChange={this.handler} />
           )
       }
   }


class ChildComponent extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
             page:1
        };
    }

    someMethod = (page) => {
        this.setState({ page: page });
        this.props.onChange(page)
    }

    render() {
        return (
       <Button
            onClick={() => this.someMethod()} 
       > Click
        </Button>
      )
   }
}

นี่ onChange เป็นคุณลักษณะที่มีวิธีการ "จัดการ" ผูกพันกับมันเป็นตัวอย่าง เราส่งเมธอด handler ไปยังคอมโพเนนต์คลาส Child เพื่อรับผ่านคุณสมบัติ onChange ในอาร์กิวเมนต์ของอุปกรณ์

แอตทริบิวต์ onChange จะถูกตั้งค่าในวัตถุอุปกรณ์ประกอบฉากเช่นนี้

props ={
onChange : this.handler
}

และส่งผ่านไปยังองค์ประกอบย่อย

ดังนั้นองค์ประกอบของเด็กสามารถเข้าถึงมูลค่าของชื่อในวัตถุอุปกรณ์ประกอบฉากเช่น props.onChange นี้

มันทำผ่านการใช้อุปกรณ์แสดงผล

ตอนนี้องค์ประกอบย่อยมีปุ่ม“ คลิก” พร้อมชุดเหตุการณ์ onclick เพื่อเรียกใช้เมธอดตัวจัดการที่ส่งผ่านไปยัง onChnge ในวัตถุอาร์กิวเมนต์ของอุปกรณ์ประกอบฉาก ดังนั้นตอนนี้ this.props.onChange ในเด็กเก็บวิธีการส่งออกในการอ้างอิง ระดับผู้ปกครอง และเครดิต: บิตและชิ้น


ขออภัย .. สำหรับความล่าช้า Here onChange เป็นแอตทริบิวต์ที่มีวิธี "ตัวจัดการ" ที่เชื่อมโยงกับอินสแตนซ์ของมัน เราส่งเมธอด handler ไปยังคอมโพเนนต์คลาส Child เพื่อรับผ่านคุณสมบัติ onChange ในอาร์กิวเมนต์ของอุปกรณ์ แอตทริบิวต์ onChange จะถูกตั้งค่าในวัตถุอุปกรณ์ประกอบฉากเช่นนี้: props = {onChange: this.handler} และส่งผ่านไปยังองค์ประกอบของเด็กดังนั้นองค์ประกอบของเด็กสามารถเข้าถึงมูลค่าของชื่อในวัตถุอุปกรณ์ประกอบฉากเช่นอุปกรณ์ประกอบฉากนี้ทำได้โดยผ่าน การใช้อุปกรณ์แสดงผล การอ้างอิงและเครดิต: [ blog.bitsrc.io/…
Preetham NT

0

นี่เป็นวิธีที่ฉันทำ

type ParentProps = {}
type ParentState = { someValue: number }
class Parent extends React.Component<ParentProps, ParentState> {
    constructor(props: ParentProps) {
        super(props)
        this.state = { someValue: 0 }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, someValue: value})
    }

    render() {
        return <div>
            <Child changeFunction={this.handleChange} defaultValue={this.state.someValue} />
            <p>Value: {this.state.someValue}</p>
        </div>
    }
}

type ChildProps = { defaultValue: number, changeFunction: (value: number) => void}
type ChildState = { anotherValue: number }
class Child extends React.Component<ChildProps, ChildState> {
    constructor(props: ChildProps) {
        super(props)
        this.state = { anotherValue: this.props.defaultValue }

        this.handleChange = this.handleChange.bind(this)
    }

    handleChange(value: number) {
        this.setState({...this.state, anotherValue: value})
        this.props.changeFunction(value)
    }

    render() {
        return <div>
            <input onChange={event => this.handleChange(Number(event.target.value))} type='number' value={this.state.anotherValue}/>
        </div>
    }
}

0

คำตอบส่วนใหญ่ที่ให้ไว้ข้างต้นใช้สำหรับการออกแบบตามปฏิกิริยา หากคุณกำลังใช้useStateในการอัพเกรด React library ล่าสุดให้ทำตามคำตอบนี้


-3
<Footer 
  action={()=>this.setState({showChart: true})}
/>

<footer className="row">
    <button type="button" onClick={this.props.action}>Edit</button>
  {console.log(this.props)}
</footer>

Try this example to write inline setState, it avoids creating another function.

มันทำให้เกิดปัญหาประสิทธิภาพ: stackoverflow.com/q/36677733/3328979
Arashsoft
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.