据我所知,React教程和文档毫不含糊地警告说,状态不应该直接变异,并且一切都应该通过setState.
我想明白为什么,确切地说,我不能直接改变状态,然后(在同一个函数中)调用this.setState({})只是为了触发render.
例如:以下代码似乎工作得很好:
const React = require('react');
const App = React.createClass({
getInitialState: function() {
return {
some: {
rather: {
deeply: {
embedded: {
stuff: 1
}}}}};
},
updateCounter: function () {
this.state.some.rather.deeply.embedded.stuff++;
this.setState({}); // just to trigger the render ...
},
render: function() {
return (
<div>
Counter value: {this.state.some.rather.deeply.embedded.stuff}
<br></br>
<button onClick={this.updateCounter}>inc</button>
</div>
);
}
});
export default App;
Run Code Online (Sandbox Code Playgroud)
我完全遵循以下约定,但我想进一步了解ReactJS如何实际运行,哪些可能出错或者是否与上述代码不是最佳的.
this.setState文档下的注释基本上确定了两个陷阱:
this.setState它可能会替换(覆盖?)你所做的突变.我不知道在上面的代码中会发生这种情况.setState …我在typescript中编写了一个简单的树视图,使用react来呈现DOM.
每个节点都必须遵循简单的界面.
interface INode {
label: string;
children: INode[];
}
Run Code Online (Sandbox Code Playgroud)
然后通过以下方式描述树:
var tree = {
label: "root",
children: [
{
label: "node 1",
children: [
{
label: "node 1.0",
children: []
},
{
label: "node 1.1",
children: []
}
]
},
{
label: "node 2",
children: []
}
]
};
Run Code Online (Sandbox Code Playgroud)
非常简单.组件现在也非常简单.对于我有的节点:
class Node extends React.Component<INode, void>{
render() {
console.log(`Rendering ${this.props.label}`);
var list = this.props.children.map((node, i) => <li key={i}><Node {...node}/></li>);
return (
<div>
<span>{this.props.label}</span>
{this.props.children.length > 0 ? <ul>{list}</ul> : ""} …Run Code Online (Sandbox Code Playgroud)