【问题标题】:Component class not rendering组件类未呈现
【发布时间】:2018-05-30 09:27:50
【问题描述】:

我在使用自制的 ReactJS 组件时遇到了一个奇怪的问题,我一定是做错了什么。

我有一个父组件,它通过 REST 服务定期接收对象数组。将接收到的元素枚举并放入 react-bootstrap ListGroup 元素中:

<Row>
        <Col sm={2}>
            <ListGroup>
                {this.state.maps.map((object, index) => {
                    return <ListGroupItem key={index}
                        onClick={() => this.setState({ currentMapSelection: object })}>
                        {object.map_name}
                    </ListGroupItem>
                })}
            </ListGroup>
        </Col>
        <Col sm={10}>
            {this.renderMapForm()}
        </Col>
</Row>

ListGroupItems 的显示工作正常。

现在我想通过单击来编辑 List 元素。为了代码分离,我想把整个编辑逻辑放到一个单独的组件(MapLoadForm)中,它会渲染一些Form元素以及更新和删除的手段。

我把渲染放到一个单独的函数中,有条件地渲染 MapLoadForm:

renderMapForm() {
  const mapForm = this.state.currentMapSelection;
  if (mapForm != undefined) {
      return <MapLoadForm map={mapForm}></MapLoadForm>
  }
  return <div></div>
}

现在的问题是,MapLoadForm 只是在第一次点击时正确呈现。对其他列表项的后续单击不再更改它。我不再看到调用 MapLoadForm 构造函数了。

如果我将return &lt;MapLoadForm map={mapForm}&gt;&lt;/MapLoadForm&gt; 替换为return &lt;Button&gt;{mapForm.map_name}&lt;/Button&gt;,我会看到每次新点击都会呈现一个新按钮。如果我将整个表单呈现逻辑放入renderMapForm() 函数的返回语句中,也会发生同样的情况。仅仅将“外包”到新组件中是行不通的。

import React from 'react';
...

export class MapLoadForm extends React.Component {
    constructor(props) {
        super(props);

    }
    ...

    render() {
           return (
              <Form style={{ marginTop: "20px" }} horizontal>
              ...
              </Form>
              )
          }

}

export default MapLoadForm;

现在的问题:这应该有效还是我完全走错了轨道?

TIA

【问题讨论】:

    标签: reactjs components rendering


    【解决方案1】:

    您缺少一个部分:每当任何组件的 props 更改时,react 都会重新渲染该组件,但重新渲染并不意味着卸载和安装该组件。这意味着相同的组件将使用新的 props 渲染,构造函数不会再次被调用。

    将此控制台放在 MapLoadForm 组件的 render 方法中,每次组件重新渲染时都会看到新值:

    console.log('props', this.props.map)

    解决方案:

    你要找的是componentWillReceiveProps生命周期方法,每当组件收到新的props,这个生命周期方法就会被调用,用新的props值重新计算,像这样:

    componentWillReceiveProps(nextProps){
       console.log('new props', nextProps);
    }
    

    componentWillReceiveProps

    componentWillReceiveProps() 在挂载组件之前调用 收到新道具。如果您需要更新状态以响应 道具更改(例如,重置它),您可以比较 this.props 和 nextProps 并使用 this.setState() 执行状态转换 这个方法。

    【讨论】:

    • 啊……当然。就是这样......非常感谢
    • 请注意:即使现在每当点击发生时我都会被调用,但如果没有任何变化,我也会被调用。 Reason 是一个计时器控制的状态获取 (REST),它更新父组件。由此componentWillReceiveProps 似乎在后代列表中移动并击中了我,即使没有任何变化。使表单条目变得不可能,因为它在下一秒内“出现故障”。我想在改变我的内部状态之前,我需要进行深度比较。此观察结果与此讨论相符:github.com/facebook/react/issues/5650
    • 是的,你需要比较一下,很高兴你得到了解决方案:)
    猜你喜欢
    • 2014-08-12
    • 2013-06-08
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 2021-02-27
    • 2020-02-19
    • 2018-01-08
    相关资源
    最近更新 更多