反应将 onClick 值从一个类传递到另一个类

Posted

技术标签:

【中文标题】反应将 onClick 值从一个类传递到另一个类【英文标题】:React passing onClick value from one class to another 【发布时间】:2018-10-09 04:43:34 【问题描述】:

在 Tournaments.js 中,我有一个锦标赛名称列表,每个名称都具有从 API 获取的唯一 ID。现在,每当我点击其中一个锦标赛名称时,我都会得到它的 ID,但我需要将此 ID 传递给 Template.js,在那里我可以根据所点击的锦标赛 ID 获取锦标赛数据。我正在尝试将道具从孩子传递给父母,但我现在完全迷失了。

Tournament.js:

import React,  Component  from "react";
import Template from './template';

const API = 'http://localhost:8080/api/tournaments';

class Tournaments extends Component 

  constructor() 
    super();
    this.state = 
      data: []
    
  

  componentDidMount() 
    fetch(API)
    .then((Response) => Response.json())
    .then((findresponse) => 
      console.log(findresponse)
      this.setState(
        data:findresponse,
      )
    )
  

  reply_click(event) 
    var targetId = event.target.getAttribute('id');
    console.log(targetId);
  

  render() 
    return(
      <div class="container">
        <div class="row">
          <div class="col-md-6 col-md-offset-3">
            <div class="jumbotron text-center">
              
                this.state.data.map((dynamicData, key) =>
                <div>
                  <a href="/#/template" id=dynamicData.id onClick=this.reply_click>dynamicData.name</a>
                  <a href="/#/addTeams"><button type="button" class="btn-lisa">Edit</button></a>
                  <Template name=dynamicData.id></Template>
                </div>
                )
              
            </div>
          </div>
        </div>
      </div>
    )
  


export default Tournaments;

模板.js:

import React,  Component  from "react";
import Parser from 'html-react-parser';
import Tournaments from "./Tournaments";
import './template.css';
import './index.css';

const tournyAPI = 'http://localhost:8080/api/tournaments';
const teamAPI = 'http://localhost:8080/api/teams'

class template extends Component 

  constructor() 
    super();
    this.state = 
      data: [],
    
  

  componentDidMount() 
    fetch(tournyAPI)
    .then((Response) => Response.json())
    .then((findresponse) => 
      this.setState(
        tournydata:findresponse.filter(res => res.id === 18),
      )
    )

所以基本上我的目标是使用 Tournament.js 中的 targetID 代替 Template.js 中 ComponentDidMount 中的“18”

【问题讨论】:

【参考方案1】:

targetID 添加到您的父状态并作为道具传递给孩子:

reply_click(event) 
  var targetId = event.target.getAttribute('id');
  this.setState( targetID );

<Template targetID=this.state.targetID

Template 中,您可以使用this.props.targetID 访问它。

您需要使用componentDidUpdate,请参阅React Child component don't update when parent component's state update

【讨论】:

这个方法也给了我未定义的无法读取属性'setState'。 你需要在你的构造函数中绑定方法:this.reply_click = this.reply_click.bind(this),或者声明为reply_click = event =&gt; 谢谢,消除了错误,但在 Template.js this.props.targetID 内仍然返回 undefined 你用this.state = targetID: null 初始化状态了吗?您还需要将您的componentDidMount 更改为componentDidUpdate;请参阅我上面提供的链接。【参考方案2】:

在您的示例中,这非常简单,因为您在循环中渲染&lt;Template&gt;,您可以将其作为参数传递

问题 1

React 的目的不是像这样操作 dom var targetId = event.target.getAttribute('id') 你有这个 id,为什么要从 DOM 中获取它?而不是接受它作为参数

 <a href="/#/template" id=dynamicData.id onClick=(e) => this.reply_click(e, dynamicData.id)>dynamicData.name</a>

reply_click(event, targetId) 

    console.log(targetId);
  

永远不要在 React 中查询 DOM。由于未安装的元素等,您会遇到混乱和错误。React 使用 JSDom(在内存中)而不是 Real DOM

问题 2

只需将其作为参数传递

并在reply_click 中调用 setState

reply_click(event, targetId) 

    console.log(targetId);
    this.setState(targetID: targetId)
  

【讨论】:

尝试使用此方法,现在我收到 TypeError: Cannot read property 'setState' of undefined。我还将 targetID 添加到构造函数的 this.state 部分 你没有改变我发送的链接......它有 onClick=() => this.reply_click 它将用这个上下文包装回调【参考方案3】:

您应该将此值保留在父组件state 中,并将其作为道具传递给子组件。

当您的onClick 被解雇时,您应该更新父母state,以便更新的props 将传递给孩子。

代码如下:

Tournament.js

import React,  Component  from "react";
import Template from './template';

const API = 'http://localhost:8080/api/tournaments';

class Tournaments extends Component 

  constructor() 
    super();
    this.state = 
      data: [],
      targetId: null,
    
  

  componentDidMount() 
    fetch(API)
    .then((Response) => Response.json())
    .then((findresponse) => 
      console.log(findresponse)
      this.setState(
        data:findresponse,
      )
    )
  

  reply_click = id => 
    return () => 
        this.setState( targetId: id )
    
  

  render() 
    return(
      <div class="container">
        <div class="row">
          <div class="col-md-6 col-md-offset-3">
            <div class="jumbotron text-center">
              
                this.state.data.map((dynamicData, key) =>
                <div>
                  <a href="/#/template" onClick=this.reply_click(dynamicData.id)>dynamicData.name</a>
                  <a href="/#/addTeams"><button type="button" class="btn-lisa">Edit</button></a>
                  <Template name=dynamicData.id targetId=this.state.targetId></Template>
                </div>
                )
              
            </div>
          </div>
        </div>
      </div>
    )
  


export default Tournaments;

Template.js

import React,  Component  from "react";
import Parser from 'html-react-parser';
import Tournaments from "./Tournaments";
import './template.css';
import './index.css';

const tournyAPI = 'http://localhost:8080/api/tournaments';
const teamAPI = 'http://localhost:8080/api/teams'

class template extends Component 

  constructor() 
    super();
    this.state = 
      data: [],
    
  

  componentDidMount() 
    fetch(tournyAPI)
    .then((Response) => Response.json())
    .then((findresponse) => 
      this.setState(
        tournydata: findresponse.filter(res => res.id === this.props.targetId),
      )
    )

但是,如果您想在每次更改 targetId 后保持更新您的 模板 组件,请使用 componentDidUpdate 而不是 componentDidMount

像这样:

Template.js

componentDidUpdate(prevProps) 
    if (prevProps.targetId !== this.props.targetId) 
       fetch(tournyAPI)
       .then((Response) => Response.json())
       .then((findresponse) => 
       this.setState(
          tournydata:findresponse.filter(res => res.id === this.props.targetId),
       )
      )
    

如果您需要在第一次渲染期间立即执行此操作,只需在您的 Tournament 组件中添加检查 targetId 是否不是 null

类似这样的:

Tournament.js

render() 
    ...
    this.state.targetId ? <Template name=dynamicData.id targetId=this.state.targetId></Template> : null 
    ...

【讨论】:

试过了,但是 this.props.targetId 在 Template.js 中返回 undefined 另外, 是否需要在渲染内部或确实它也可以在渲染之外工作? @Ferder 我已经在我的回答中更新了你的 reply_click 函数。像这样使用它。 @Ferder 你是怎么试过的,用哪一个? componentDidMountcomponentDidUpdate? componentDidUpdate @Ferder 尝试将它与更新的reply_click 函数一起使用并像我一样更改onClick

以上是关于反应将 onClick 值从一个类传递到另一个类的主要内容,如果未能解决你的问题,请参考以下文章

使用列表将值从一个类传输到另一个类

如何制作一个删除消息并根据反应将其发布到另一个频道的机器人

如何将值从 Item Click RecyclerView 发送到另一个 java 类

C ++将值从一个类传递到抽象类

将 Jquery 中的值从一个 html 类传递到 PhoneGap 中的另一个 html 类

将值从一个组件传递到另一个组件