当我在这样的网格上强制更新时,我收到以下警告:
proxyConsole.js:56 Warning: forceUpdate(...): Cannot update during an existing state transition (such as within `render` or another component's constructor). Render methods should be a pure function of props and state; constructor side-effects are an anti-pattern, but can be moved to `componentWillMount`.
不确定如何修改放置forceUpdate()
的位置以使其正常运行。
const quoteList = [];
class App extends Component {
constructor() {
super();
this.state = {
response: {},
endpoint: "http://127.0.0.1:4001"
};
}
componentDidMount() {
const { endpoint } = this.state;
const socket = socketIOClient(endpoint);
this.theGrid.forceUpdate();
socket.on("FromAPI", data => this.setState({ response: data }));
}
cellRenderer ({ columnIndex, key, rowIndex, style }) {
return (
<div
key={key}
style={style}
>
{quoteList[rowIndex][columnIndex]}
</div>
)
}
render() {
const { response } = this.state;
if(Object.keys(response).length !== 0)
{
//console.log(response);
const row = symbolRowDictionary[response.ticker];
var column = 0;
switch(response.type)
{
case 'bid':
column = 1;
break;
case 'ask':
column = 3;
break;
case 'last':
column = 5;
break;
default:
console.log('Unknown type');
}
quoteList[row][column] = response.size;
quoteList[row][column + 1] = response.price;
this.theGrid.forceUpdate();
}
return (
<div style={{ textAlign: "center" }}>
{
<ul><li>Quote: {response.ticker} {response.type} {response.price} {response.size}</li></ul>
}
<div>
</div>
<Grid
ref={(ref) => this.theGrid = ref}
cellRenderer={this.cellRenderer}
columnCount={7}
columnWidth={75}
height={quoteList.length * 20}
rowCount={quoteList.length}
rowHeight={20}
width={800}
/>
</div>
);
}
}
export default App;
答案 0 :(得分:0)
我会将quoteList
移动到组件state
,如下所示:
const endpoint: "http://127.0.0.1:4001";
class App extends Component {
constructor() {
super();
this.state = {
response: {},
quoteList = [];
};
}
componentDidMount() {
const socket = socketIOClient(endpoint);
let _this = this;
let {quoteList} = this.state;
socket.on("FromAPI", data => {
if(Object.keys(response).length !== 0) {
const row = symbolRowDictionary[response.ticker];
var column = 0;
switch(response.type)
{
case 'bid':
column = 1;
break;
case 'ask':
column = 3;
break;
case 'last':
column = 5;
break;
default:
console.log('Unknown type');
}
quoteList[row][column] = response.size;
quoteList[row][column + 1] = response.price;
_this.setState({ response: data, quoteList: quoteList })
}
}));
}
cellRenderer ({ columnIndex, key, rowIndex, style }) {
let {quoteList} = this.state;
return (
<div
key={key}
style={style}
>
{quoteList[rowIndex][columnIndex]}
</div>
)
}
render() {
const { response, quoteList } = this.state;
return (
<div style={{ textAlign: "center" }}>
{
<ul><li>Quote: {response.ticker} {response.type} {response.price} {response.size}</li></ul>
}
<div>
</div>
<Grid
ref={(ref) => this.theGrid = ref}
cellRenderer={this.cellRenderer}
columnCount={7}
columnWidth={75}
height={quoteList.length * 20}
rowCount={quoteList.length}
rowHeight={20}
width={800}
/>
</div>
);
}
}
export default App;
&#13;
更新quoteList
后,其length
将相应更新,这些更改将传递给子组件Grid
修改强>
由于你不明白为什么这个代码运行,我会解释一下。如果您不了解React生命周期,请查看此illustration
quoteList
在constructor
render
是第一次被召唤。 cellRenderer
将绑定到此组件,或this
指向App
组件。componentDidMount
。这是我们应该从API获取数据的时间。在功能块(data => {...}
)内,this
指向函数本身。因此,在获取API之前,我必须指定_this = this
才能调用setState
。setState
已执行,render
将再次触发,因为quoteList
已更改。根据新App
,您的quoteList
将以不同方式呈现。表示新的quoteList
现已传递到您的Grid
。 Grid
也会重新渲染。 通过此流程,您不需要forceUpdate
。
答案 1 :(得分:0)
经过大量实验和一些在线文档后,我能够通过这样设置this.theGrid.forceUpdate
来解决它。没有任何警告,render
和rendercell
保持纯正&#34;
componentDidMount() {
const socket = socketIOClient(endpoint);
socket.on("FromAPI", data =>
{
this.setState({ response: data });
this.theGrid.forceUpdate();
}
);
}