html - 如何在别人的 onclick 上更改反应组件
问题描述
我正在构建一个 React 应用程序,我在其中渲染一个家谱。为此,在每个家谱组件节点中,我添加了一个 onclick,它打开一个模式(又名弹出表单),允许用户编辑该人的信息。在那个模式/弹出窗口中,我在底部有一个提交按钮。我想要它,以便在单击提交按钮时,在树中的相应节点上获取并更新表单中的输入字段(例如:姓名、父母等)。我在我的代码中试过这个:
submitbtn.onclick = () => {
alert("couple submit clicked!");
info.husband = document.getElementById("hname_inp").value;
info.wife = document.getElementById("wname_inp").value;
modal.style.display = 'none';
alert(info.husband + ' ' + info.wife)
};
return (
<li>
<div onClick={handleClick}>
<span className="male">{info.husband}</span>
<span className="spacer"></span>
<span className="female">{info.wife}</span>
</div>
<Children />
</li>
);
默认情况下,组件会显示通过 props 传递的信息。单击提交按钮时,我希望输入字段中的数据替换组件中的数据。onclick 和数据很好,但组件没有更新。我是 React 新手,所以这可能只是一个愚蠢的错误,请与我裸露。最后,这是一个小话题,但是当我单击提交按钮时,屏幕闪烁一秒钟,出现一个没有格式的 html 页面,然后它恢复正常。这可能是什么原因?
编辑(新代码):
import React from "react";
export default class Couple extends React.Component {
constructor(props) {
super(props);
this.state = {
husband: this.props.husband,
wife: this.props.wife,
};
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
const newState = this.state
const modal = document.getElementById('coupleModal');
modal.style.display = 'block';
const submitbtn = document.getElementById('couplesubmitbtn');
submitbtn.onClick = (event) => {
event.preventDefault()
modal.style.display = 'none'
newState.husband = document.getElementById('hname').value;
newState.wife = document.getElementById('wname').value;
}
this.setState(newState);
}
render() {
const children = this.props.children;
return (
<li>
<div onClick={this.handleClick}>
<span className="male">{this.state.husband}</span>
<span className="spacer"></span>
<span className="female">{this.state.wife}</span>
</div>
{children != null && children.length !== 0 ? <ul>{children}</ul> : ""}
</li>
);
}
}
解决方案
正如之前的评论中提到的,如果你能提供一个小提琴等来看看,那就太好了。
您提到您是 React 的新手,所以即使冒着听起来很愚蠢的风险,我想问一下您是否在这里使用了一些状态处理?如果没有,那么它可能需要调查。如果您已经熟悉 React 状态,那么这个答案是没有意义的,应该被忽略。
在 reactjs.org 中有很多关于 state 和 props 有什么区别的文档?
setState() 安排对组件状态对象的更新。当状态改变时,组件通过重新渲染来响应。
https://reactjs.org/docs/faq-state.html#what-is-the-difference-between-state-and-props
因此,在这种情况下,有关您的家谱的信息将被初始化为状态,然后弹出窗口应通过 setState 更新状态。然后新的输入得到更新并重新呈现 UI 组件。
如果我是对的并且状态处理将帮助您继续前进,我还建议您查看 React Hooks。Hooks 是 React 16.8 中的新增功能,当您掌握了状态的概念时,使用 Hooks 将是编写应用程序的一种简单且更优雅的方式
==================== 第 2 部分 ====================
这是您在下面的评论中提出的问题的答案和一些其他想法:
我认为闪烁实际上是提交时刷新页面。因此,捕获用户事件并将其传递并调用 preventDefault() 是一种方法。下面我举个例子。
看着你的代码,我越来越相信你确实缺乏状态处理,这是这里最初的问题。阅读更多关于它的内容真的会让你受益匪浅。同时它会帮助你更好地理解 React 通常是如何工作的逻辑。
这是另一个可能值得一试的链接: https ://www.freecodecamp.org/news/get-pro-with-react-setstate-in-10-minutes-d38251d1c781/
最后是codeSnippet。请注意,您尝试定位的妻子输入元素getElementById
应该document.getElementById("hname")
是document.getElementById("hname_inp")
submitbtn.onclick = (event) => {
event.preventDefault();
console.log(props.wife);
modal.style.display = "none";
info.husband = document.getElementById("name").value;
info.wife = document.getElementById("hname").value;
alert(info.husband + " " + info.wife);
};
==================== 第 3 部分 ====================
很高兴看到您仔细研究了状态处理并进行了尝试。我会继续通过一些额外的阅读来积累知识。这是一篇关于 Reacts 数据处理的好文章。
因此,与其在不同的组件中分别使用状态处理,我建议您将其移至 App.js,因为它是其他组件的明显父组件。在那里你还应该考虑数据结构。我假设这个项目不会连接(至少现在)任何 api 或数据库,所以它也将在这里处理。
因此,为 App.js 定义某种基线可能看起来像这样。
this.state = {
state = { family : [
[{ name: 'kari', gender: male }]
[
{ name: 'jasper', gender: male },
{ name: 'tove', gender: femmale }
],
]
}
}
那么我建议你也将处理程序移到这里。然后把它们写在这里,你甚至可能不再需要单独的情侣和单身人士了。
我很遗憾听到你仍然看到闪烁。我对此的最佳猜测是模态不知道 event.preventDefault。为了清楚起见,我也会对此进行一些重构。通常,尝试通过 React 中的 getElements 修改内容并不是一个好习惯。通常都是状态和道具。所以我在这里添加了几行代码作为你如何继续的例子
import React from "react";
import SingleModal from "./Modals/SingleModal";
export default class Couple extends React.Component {
constructor(props) {
super(props);
this.state = {
visible: false,
};
this.popUpHandler = this.popUpHandler.bind(this);
}
popUpHandler(event) {
event.preventDefault()
this.setState({visible: !this.state.visible})
}
render(props) {
return (
<>
<SingleModal visible={this.state.visible} popUpHandler={this.popUpHandler }/>
<li>
<div onClick={this.popUpHandler}>
<span className={this.props.gender}>{this.props.name}</span>
</div>
</li>
</>
);
}
}
在 SingleModal 中类似地摆脱了这样的表单提交:
<input
type="submit"
value="Submit"
className="submit"
id="singlesubmitbtn"
onClick={(e) => {
e.preventDefault();
props.popUpHandler(e)
}}
/>
PS。我想这将是我在这里对这个问题的最后一个答案。答案太长了,并且开始偏离原始问题的主题。祝你的项目好运
推荐阅读
- javascript - 循环中的承诺问题。数据被多次输出。比如第三次循环,它记录了三次数据
- javascript - 在 Puppeteer 中截取具有特定名称的不同元素的屏幕截图
- javascript - Puppeteer Bright Data 代理返回 ERR_NO_SUPPORTED_PROXY 或 CERT 错误
- node.js - 如何授权 3rd 方服务访问我的 API
- hive - Impala 游标行数给出错误 GetRuntimeProfile not found
- python - 用另一个数据框的值替换数据框列列表值
- listview - ListView 单元格绑定未在集合中找到方法
- powershell - 如何摆脱形状标签
- node.js - 无法安装 Webpack 5 ERESOLVE
- node.js - 如何从猫鼬的另一个集合中添加现有文档的元素?