首页 > 解决方案 > 如何在别人的 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>
    );
  }
}

标签: htmlreactjs

解决方案


正如之前的评论中提到的,如果你能提供一个小提琴等来看看,那就太好了。

您提到您是 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 数据处理的好文章。

https://towardsdatascience.com/passing-data-between-react-components-parent-children-siblings-a64f89e24ecf

因此,与其在不同的组件中分别使用状态处理,我建议您将其移至 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。我想这将是我在这里对这个问题的最后一个答案。答案太长了,并且开始偏离原始问题的主题。祝你的项目好运


推荐阅读