基本代码流是这样的。
export default class Item extends React.Component {
constructor(props) {
super(props);
this.state = {
modalIsOpen: false,
logs: []
};
this._fetchLogs = this._fetchLogs.bind(this);
this._fetchAnotherLogs = this._fetchAnotherLogs.bind(this);
}
render() {
let tableBody;
if (this.state.logs.length > 0) {
let body = [];
this.state.logs.forEach((log) => {
body.push(
<tr key={`log${log.id}`}>
<td>{log.operator_name} / {log.operator_code}</td>
</tr>
);
});
tableBody = (
<table className="logs">
<thead>
<tr>
<th className="operator">{i18next.t('operator')}</th>
</tr>
</thead>
<tbody>{body}</tbody>
</table>
);
}
return (
<div>
<ul className="tabs">
<li onClick={this._fetchLogs}>Logs</li>
<li onClick={this._fetchAnotherLogs}>Another Logs</li>
</ul>
<div className="modalContent">
{tableBody}
</div>
</div>
);
}
componentDidUpdate() {
console.log('didUpdate', $('.ReactModal__Content').height(), $(window).height());
}
_fetchLogs() {
$.ajax({
context: this,
url: URL.DEVICE_LOGS(this.props.id),
success(resp) {
const logs = resp.data;
this.setState({logs});
},
error(resp) {
console.log(resp);
},
});
}
_fetchAnotherLogs() {
$.ajax({
context: this,
url: URL.DEVICE_LOGS_ANOTHER(this.props.id),
success(resp) {
const logs = resp.data;
this.setState({logs});
},
error(resp) {
console.log(resp);
},
});
}
};
因此,当单击<li>
元素时,它会调用_fetchLogs()
,它将logs
状态设置为服务器中的某个数组,而在render()
内,它会设置tableBody
变量并填充<div className="modalContent">
。
我想要实现的是通过在状态更改后使用jQuery并且组件重新呈现表,测量表的高度并相应地更改一些样式。
但是componentDidUpdate()
注销的是所有孩子(例如,<table>
)被重新渲染之前的高度。
例如,如果我说默认高度(没有<table
&gt;内容)是170px,则后高(日志的<table>
内容)是340px,后高(其他日志的<table>
内容为500px,当我第一次点击<li>
时,它表示高度为170px,但实际结果高度为340px。如果我点击另一个<li>
来获取另一个日志,现在它说高度是340px,这也是错误的,因为它应该是500px。
所以我认为componentDidUpdate()
仅在状态发生变化后被调用,而不是实际重新渲染(由于状态变化)完成。是否存在我做错的事情,或者我应该考虑其他选择吗?
根据Matthew Herbst的回答,我认为这个回答是合理的,我做了几个改变,但它并没有真正改变。
<div className="modalContent" ref={c => this._modalContent = c}>
{tableBody}
</div>
和
componentDidUpdate() {
console.log('didUpdate', this._modalContent.offsetHeight);
}
(我也尝试用jQuery包装它,但它没有改变......)
我试图通过在componentDidUpdate()
console.log()
之前添加render()
来注销渲染序列和return
(尽管无法实现此目的)方式,我知道),它清楚地表明对象数组日志出现在didUpdate
日志之前。
答案 0 :(得分:0)
所以,这里发生的事情是你实际上没有访问componentDidMount
中的组件,你正在访问DOM,即使你的组件已经渲染,它可能还没有更新(记住,React有渲染可能已更新的所有组件,然后执行单个DOM差异。
您使用componentDidUpdate
是正确的,但您只是访问了错误的内容。你需要的是refs
。
在render
中,添加ref
:
return (
<div>
<ul className="tabs">
<li onClick={this._fetchLogs}>Logs</li>
<li onClick={this._fetchAnotherLogs}>Another Logs</li>
</ul>
<div
className="modalContent"
ref={(myTableRef) => this.myTableRef = myTableRef}
>
{tableBody}
</div>
</div>
);
然后在componentDidUpdate
中,您可以执行以下操作:
componentDidUpdate() {
console.log('didUpdate', $(this.myTableRef).height(), $(window).height());
}
这应该为您提供表格模型的正确高度。