Asp.net 核心 2.0 上的 React 中的子与父通信

Child to parent communication in React on Asp.net core 2.0

我在 asp.net 核心 2.0 中有一个 React 应用程序(不是 ReactJs),但我遇到了问题。我有一个需要与父组件通信的子组件。具体来说,当单击子组件中的按钮时,我需要将其转发给父组件。这就是我所拥有的,但我不能完全让它发挥作用...

子组件:

export class Buttons extends React.Component<any, any> {

  buttonClick(idx) {
    //I would like to notify parent component here
    //that Button (idx) was clicked
    return idx
  }

  public render() {
    return <div>
        <button onClick={this.buttonClick}>Button 1</button>
        <button onClick={this.buttonClick}>Button 2</button>
        <button onClick={this.buttonClick}>Button 3</button>
        <button onClick={this.buttonClick}>Button 4</button>
    </div>;
  }
}

父组件:

export class Home extends React.Component<RouteComponentProps<{}>, {}> {

  ...
  handler(idx) {
    //need idx here
  }

  return <div>
        {content}
        <h1>Buttons</h1>
        <Buttons buttonClick={this.handler} />
    </div>;
}

尝试在您的子组件中执行此操作:

export default class Buttons extends React.Component {

  buttonClick = (idx) => {
    this.props.buttonClick(idx);
  }

  public render() {
    return <div>
        <button onClick={this.buttonClick(1)}>Button 1</button>
        <button onClick={this.buttonClick(2)}>Button 2</button>
        <button onClick={this.buttonClick(3)}>Button 3</button>
        <button onClick={this.buttonClick(4)}>Button 4</button>
    </div>;
  }
}

这里有 2 个主要选项,
简单的解决方案,但被认为是 不好的做法
有点复杂,但被认为是好的做法

  • 简单的解决方法:
    使用柯里化将 id 的参数传递给处理程序:
    这是不好的做法,因为它会创建一个新的函数实例 在每个渲染器上,当您在每个渲染器上传递新道具时,这可能会导致性能问题,这可能会中断 diffing algorithm of react.

       
       class Buttons extends React.Component {
         constructor(props) {
           super(props);
       
           this.buttonClick = this.buttonClick.bind(this);
         }
         
         buttonClick(idx) {
           const that = this;
           return function (e) {
             that.props.buttonClick(idx);
           }
         }
       
         render() {
           return <div>
             <button onClick={this.buttonClick(1)}>Button 1</button>
             <button onClick={this.buttonClick(2)}>Button 2</button>
             <button onClick={this.buttonClick(3)}>Button 3</button>
             <button onClick={this.buttonClick(4)}>Button 4</button>
           </div>;
         }
       }
       
       
       class App extends React.Component {
         constructor(props) {
           super(props);
           this.state = {};
       
           this.handler = this.handler.bind(this);
         }
       
         handler(idx) {
           console.log(idx);
         }
       
         render() {
           return (
             <div>
               <h1>Buttons</h1>
               <Buttons buttonClick={this.handler} />
             </div>
           );
         }
       }
       
       ReactDOM.render(<App />, 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>
       
       
    

  • 更好的解决方案:
    使用组件处理 id 并将其向上传递给处理程序。
    这是一个很好的做法,因为您正在使用组件组合,它可以让您重用代码、测试它并更好地维护和调试它,而且当您在每个渲染器上创建新实例时不会遇到性能问题。

       
       class MyButton extends React.Component{
         constructor(props) {
           super(props);
       
           this.buttonClick = this.buttonClick.bind(this);
         }
         buttonClick(idx) {
             this.props.buttonClick(this.props.buttonId);
         }
       
         render(){
           return(
             <button onClick={this.buttonClick}>{this.props.children}</button>
           );
         }
       }
       
       class Buttons extends React.Component {
       
         render() {
           return <div>
             <MyButton buttonClick={this.props.buttonClick} buttonId={1}>Button 1</MyButton>
             <MyButton buttonClick={this.props.buttonClick} buttonId={2}>Button 2</MyButton>
             <MyButton buttonClick={this.props.buttonClick} buttonId={3}>Button 3</MyButton>
             <MyButton buttonClick={this.props.buttonClick} buttonId={4}>Button 4</MyButton>
           </div>;
         }
       }
       
       
       class App extends React.Component {
         constructor(props) {
           super(props);
           this.state = {};
       
           this.handler = this.handler.bind(this);
         }
       
         handler(idx) {
           console.log(idx);
         }
       
         render() {
           return (
             <div>
               <h1>Buttons</h1>
               <Buttons buttonClick={this.handler} />
             </div>
           );
         }
       }
       
       ReactDOM.render(<App />, 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>