如何从Reactjs组件的状态对象中删除属性

Jos*_*hua 25 state reactjs

如果我有一个在其状态上设置了属性的react组件:

onClick() {
    this.setState({ foo: 'bar' });
}
Run Code Online (Sandbox Code Playgroud)

是否有可能从"foo"这里删除Object.keys(this.state)

replaceState方法看似明显的方法来尝试,但它至今已贬值.

Ale*_* T. 24

您可以设置fooundefined,像这样

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)

Example

你也可以用delete,

delete this.state.foo;
this.setState(this.state);
Run Code Online (Sandbox Code Playgroud)

但这很危险,因为这个解决方案直接操作this.state

更新

以前的解决方案只是删除了值fookey技能存在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)

});

  • 不知道为什么这会被否决,这是 100% 正确的答案 (2认同)
  • 如果设置了key和value,则该操作不会删除该key (2认同)

Ste*_*per 5

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 之类的已弃用功能等恐怖事件