反应将 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 =>
。
谢谢,消除了错误,但在 Template.js this.props.targetID 内仍然返回 undefined
你用this.state = targetID: null
初始化状态了吗?您还需要将您的componentDidMount
更改为componentDidUpdate
;请参阅我上面提供的链接。【参考方案2】:
在您的示例中,这非常简单,因为您在循环中渲染<Template>
,您可以将其作为参数传递
问题 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 你是怎么试过的,用哪一个? componentDidMount
或 componentDidUpdate
?
componentDidUpdate
@Ferder 尝试将它与更新的reply_click
函数一起使用并像我一样更改onClick
以上是关于反应将 onClick 值从一个类传递到另一个类的主要内容,如果未能解决你的问题,请参考以下文章
如何将值从 Item Click RecyclerView 发送到另一个 java 类