我对自制的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 <MapLoadForm map={mapForm}></MapLoadForm>
替换为return <Button>{mapForm.map_name}</Button>
,我会看到每次新点击都会呈现一个新按钮。如果我将整个Form呈现逻辑放入renderMapForm()
函数的return语句中,也会发生同样的情况。只是&#34;外包&#34;进入一个新的组件是行不通的。
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
答案 0 :(得分:1)
您缺少一个部分:每当任何组件的道具发生变化时,反应重新渲染该组件,但重新渲染并不意味着卸载和安装组件。这意味着相同的组件将使用新的道具呈现,构造函数将不再被调用。
将此控制台放在MapLoadForm组件的render方法中,每次组件重新渲染时都会看到新值:
console.log('props', this.props.map)
<强>解决方案:强>
您正在寻找的是componentWillReceiveProps
生命周期方法,每当组件收到新道具时,此生命周期方法将被调用,再次使用新道具值进行计算,如下所示:
componentWillReceiveProps(nextProps){
console.log('new props', nextProps);
}
<强> componentWillReceiveProps 强>
在安装的组件之前调用componentWillReceiveProps() 收到新的道具。如果您需要更新状态以响应 prop更改(例如,重置它),您可以比较this.props 和nextProps并使用this.setState()执行状态转换 这种方法。