简体   繁体   English

如何从componentDidMount()(不是componentDidUpdate())更新DOM中的状态对象?

[英]How to update a state object in the DOM from componentDidMount() (not componentDidUpdate())?

I'm trying to conditionally show or not show per say a button based on data that I receive from clicking on a point. 我试图根据我从点击某个点收到的数据来有条件地显示或不显示一个按钮。 I realized that regular jquery functions to add a class don't really work in React. 我意识到,常规的添加类的jquery函数在React中实际上并不起作用。 So I figured I could store strings in the state like 所以我想我可以像这样存储字符串

this.state: {
    hidden_components: {
        add_comment: "hide"
    }
}

This way I can conditionally show or hide a button by 这样我可以有条件地显示或隐藏按钮

<button className={this.state.hidden_components.add_comment}> Add Comment </button>

After the render() I have more or less: 在render()之后,我或多或少有:

componentDidMount() {
  this.state.g = new Dygraph
  this.state.modal = new Modal 

  this.state.modal.setContent(use some ID here to reference a div that is hidden but will show up in the modal)

  const set_hidden_container = () => {
      // I'm just going to use this = notation instead of setState()
      // this is supposed to reset the 
      this.state.hidden_components = "hide"
      if (check_comment(this.state.points[at some index].value)) {
        this.state.hidden_components = "show"
      }
  }

  this.state.g.updateOptions( {

    pointClickCallback: (event, p) => {
      console.log("i clicked a point on the graph")
      this.setState({
        currentPoint: p
      })

      set_hidden_containers()

      // force update
      this.setState({
        currentPoint: p
      })

      // I want the modal to open a div of things that only show jsx based on logic in set_hidden_container()
      this.state.modal.open()
    }
  }

componentDidUpdate() {
  // logic goes here for like event listeners and anything that queries the DOM after initialization
}

Then in componentDidMount() I have a function that depending on the data received from clicking on a point I do the following: 1) reset all the classes stored in the state to "hide" 2) based on conditions set some of them to "show" 3) concatenate all the classes stored in the state with various styling classes 然后在componentDidMount()中,我有一个函数,该函数根据单击某点时收到的数据进行以下操作:1)将状态中存储的所有类重置为“隐藏” 2)根据条件将其中一些设置为“ show“ 3)将状态中存储的所有类与各种样式类连接起来

UPDATE: I've long since found an easier solution to this problem, however, I'm guessing some people might have similar issues. 更新:我早就找到了解决这个问题的简便方法,但是,我猜有些人可能也有类似的问题。 Therefore, I'll update this question with more psuedocode and a workaround: maybe someone down the line can solve this. 因此,我将通过更多的伪代码和变通方法来更新此问题:也许有人可以解决这个问题。 This component is particularly frustrating to work with because I haven't been able to make it as modular as I want because of the particular library I'm working with. 使用该组件特别令人沮丧,因为由于要使用的特定库,我无法使其像我想要的那样模块化。 There are actually about a 1000 lines in this component (I know I know not good). 实际上,此组件中大约有1000行(我知道我知道不好)。

WORKAROUND: For those of you who are having trouble with a component's lifecycle in dynamically setting parts of the DOM but don't want to use global variables to set classNames, jquery functions, or use react syntax to show components containing the content I recommend you do the following. 变通方法:对于那些在动态设置DOM的一部分时遇到组件生命周期问题,但又不想使用全局变量来设置classNames,jquery函数或使用react语法来显示包含我推荐内容的组件的用户请执行下列操作。

You can still have a set_hidden_container() set content dynamically, you just have to set things based on an id with innerHTML instead of setting a state object to be a string "show". 您仍然可以通过set_hidden_​​container()动态设置内容,只需使用innerHTML根据ID设置内容,而不是将状态对象设置为字符串“ show”。 The important thing is, however, that for every time you need to dynamically change content you reset these references to be empty as well as force an update. 但是,重要的是,每次需要动态更改内容时,都将这些引用重置为空并强制进行更新。 You can simply change the state of anything and then in componentDidUpdate() you can insert 1) a conditional to check if the innerHTML was actually set or not (since you're not always going to be displaying everything) and 2) within that conditional you can set whatever logic you want associated with the content showing on the page. 您可以简单地更改任何内容的状态,然后在componentDidUpdate()中插入1)一个条件,以检查是否确实设置了innerHTML(因为您不一定总是显示所有内容),以及2)在该条件内您可以设置要与页面上显示的内容相关联的任何逻辑。

componentDidMount is invoked immediately after a component is mounted. componentDidMount一个部件被安装之后被立即调用。 If you want to set classNames based on clicks, I would put that logic in componentDidUpdate , which is invoked after updating occurs. 如果要基于单击设置classNames,我会将其放在componentDidUpdate中 ,该逻辑在更新发生后被调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM