如果我有一个在其状态上设置了属性的react组件:
onClick() {
this.setState({ foo: 'bar' });
}
Run Code Online (Sandbox Code Playgroud)
是否有可能从"foo"这里删除Object.keys(this.state)?
该replaceState方法看似明显的方法来尝试,但它至今已贬值.
Ale*_* T. 24
您可以设置foo到undefined,像这样
var Hello = React.createClass({
getInitialState: function () {
return {
foo: 10,
bar: 10
}
},
handleClick: function () {
this.setState({ foo: undefined });
},
render: function() {
return (
<div>
<div onClick={ this.handleClick.bind(this) }>Remove foo</div>
<div>Foo { this.state.foo }</div>
<div>Bar { this.state.bar }</div>
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
你也可以用delete,
delete this.state.foo;
this.setState(this.state);
Run Code Online (Sandbox Code Playgroud)
但这很危险,因为这个解决方案直接操作this.state
更新
以前的解决方案只是删除了值foo和key技能存在state,如果你需要完全删除键state,其中一个可能的解决方案可以是setState一个父key,如此
var Hello = React.createClass({
getInitialState: function () {
return {
data: {
foo: 10,
bar: 10
}
}
},
handleClick: function () {
const state = {
data: _.omit(this.state.data, 'foo')
};
this.setState(state, () => {
console.log(this.state);
});
},
render: function() {
return (
<div>
<div onClick={ this.handleClick }>Remove foo</div>
<div>Foo { this.state.data.foo }</div>
<div>Bar { this.state.data.bar }</div>
</div>
);
}
});
ReactDOM.render(<Hello />, document.getElementById('container'))Run Code Online (Sandbox Code Playgroud)
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="container"></div>Run Code Online (Sandbox Code Playgroud)
GAU*_*RAV 22
var Hello = React.createClass({
getInitialState: function () {
return {
foo: 10,
bar: 10
}
},
handleClick: function () {
let state = {...this.state};
delete state.foo;
this.setState(state);
},
render: function() {
return (
<div>
<div onClick={ this.handleClick.bind(this) }>Remove foo</div>
<div>Foo { this.state.foo }</div>
<div>Bar { this.state.bar }</div>
</div>
);
}
Run Code Online (Sandbox Code Playgroud)
});
在ReactCompositeComponent.jsGitHub 上的 React 源中有一个方法叫做_processPendingState,它是实现从调用 component.setState 合并状态的终极方法;
``` _processPendingState: function(props, context) { var inst = this._instance; var queue = this._pendingStateQueue; var replace = this._pendingReplaceState; this._pendingReplaceState = false; this._pendingStateQueue = null;
if (!queue) {
return inst.state;
}
if (replace && queue.length === 1) {
return queue[0];
}
var nextState = replace ? queue[0] : inst.state;
var dontMutate = true;
for (var i = replace ? 1 : 0; i < queue.length; i++) {
var partial = queue[i];
let partialState = typeof partial === 'function'
? partial.call(inst, nextState, props, context)
: partial;
if (partialState) {
if (dontMutate) {
dontMutate = false;
nextState = Object.assign({}, nextState, partialState);
} else {
Object.assign(nextState, partialState);
}
}
}
Run Code Online (Sandbox Code Playgroud)
``
在该代码中,您可以看到实现合并的实际行;
nextState = Object.assign({}, nextState, partialState);
Run Code Online (Sandbox Code Playgroud)
在这个函数中没有任何地方调用delete或类似,这意味着它不是真正的预期行为。此外,完全复制统计信息、删除属性和调用 setState 将不起作用,因为 setState 始终是一个合并,因此将忽略已删除的属性。
还要注意 setState 不会立即生效,而是批量更改,因此如果您尝试克隆整个 state 对象并且只更改一个属性,您可能会清除之前对 setState 的调用。正如 React 文档所说;
React 可以将多个 setState() 调用批处理为单个更新以提高性能。
因为 this.props 和 this.state 可能会异步更新,所以你不应该依赖它们的值来计算下一个状态。
您实际上可以做的是添加更多信息;
this.setState({ xSet: true, x: 'foo' });
this.setState({ xSet: false, x: undefined });
Run Code Online (Sandbox Code Playgroud)
这是丑陋的,当然,但它为您提供了额外的信息,您需要区分设置为未定义的值和根本未设置的值。此外,它与 React 的内部结构、事务、状态更改批处理和任何其他恐怖功能配合得很好。最好在这里采取一些额外的复杂性,而不是尝试猜测 Reacts 内部结构,它充满了诸如事务协调、管理诸如 replaceState 之类的已弃用功能等恐怖事件
| 归档时间: |
|
| 查看次数: |
49085 次 |
| 最近记录: |