【问题标题】:setState vs replaceState in React.jsReact.js 中的 setState 与 replaceState
【发布时间】:2014-04-25 12:48:07
【问题描述】:

我是 React.js 库的新手,我正在阅读一些教程,结果发现:

  • this.setState
  • this.replaceState

给出的描述不是很清楚(IMO)。

setState is done to 'set' the state of a value, even if its already set 
in the 'getInitialState' function.

同样,

The replaceState() method is for when you want to clear out the values 
already in state, and add new ones.

我尝试了 this.setState({data: someArray}); 然后是 this.replaceState({test: someArray}); 然后 console.logged 他们,我发现 state 现在有 datatest .

然后,我尝试了 this.setState({data: someArray});,然后是 this.setState({test: someArray});,然后 console.logged 它们,我发现 state 再次同时具有 data 和 @ 987654334@.

那么,这两者到底有什么区别呢?

【问题讨论】:

  • 您的第一个示例不准确。 replaceState 将删除以前的状态。您可能测试不正确。
  • 我不是在寻找回调中的变化。也许这就是为什么..

标签: javascript frontend reactjs


【解决方案1】:

setState 可以合并当前和以前的状态。使用replaceState,它会抛出当前状态,并仅用您提供的内容替换它。通常使用setState,除非您出于某种原因确实需要删除密钥;但是将它们设置为 false/null 通常是一种更明确的策略。

虽然它可能会改变; replaceState 当前使用作为状态传递的对象,即replaceState(x),一旦设置为this.state === x。这比setState 轻一点,所以如果成千上万的组件经常设置它们的状态,它可以用作优化。
我用this test case 断言了这一点。


如果你当前的状态是{a: 1},而你调用this.setState({b: 2});当状态被应用时,它将是{a: 1, b: 2}。如果您调用this.replaceState({b: 2}),您的状态将是{b: 2}

旁注:状态不是立即设置的,所以在测试时不要使用this.setState({b: 1}); console.log(this.state)

【讨论】:

  • 我还不清楚。你能举一个例子,使用一个而不是另一个改变结果,即你所指的这种合并......
  • 如何存在先前状态和当前状态,如,我们如何访问它们?另外,我确实传递了一个对象来替换状态,但之前的状态数据仍然存在。
  • 那么什么时候设置状态?我什么时候可以 console.log 它并测试它?
  • @myusuf .setState({...}, callback)
【解决方案2】:

实例定义:

// let's say that this.state is {foo: 42}

this.setState({bar: 117})

// this.state is now {foo: 42, bar: 117}

this.setState({foo: 43})

// this.state is now {foo: 43, bar: 117}

this.replaceState({baz: "hello"})

// this.state. is now {baz: "hello"}

请注意docs 中的这一点:

setState() 不会立即改变 this.state 而是创建一个 等待状态转换。调用 this 后访问 this.state 方法可能会返回现有值。

replaceState() 也是如此

【讨论】:

    【解决方案3】:

    根据docsreplaceState 可能会被弃用:

    此方法在扩展 React.Component 的 ES6 类组件上不可用。它可能会在未来版本的 React 中完全删除。

    【讨论】:

    • 有类似的替换方法吗?
    • 对于“类似”的方法,您可以使用 this.setState({all:undefined,old:undefined,keys:undefined,new:value})
    • @Wren,这是什么?这是要重置状态的官方签名吗?
    • 不,它只是将预先存在的状态显式设置为未定义,这是“replaceState”在没有所有现有键的情况下的最终结果。
    【解决方案4】:

    由于replaceState 现在已弃用,这里有一个非常简单的解决方法。尽管您可能很少/应该求助于需要这个。

    移除状态:

    for (const old_key of Object.keys(this.state))
        this.setState({ [old_key]: undefined });
    

    或者,如果您不想多次调用setState

    const new_state = {};
    for (const old_key of Object.keys(this.state))
        new_state[old_key] = undefined;
    this.setState(new_state);
    

    基本上,状态中所有以前的键现在都返回undefined,可以很容易地用if 语句过滤:

    if (this.state.some_old_key) {
        // work with key
    } else {
        // key is undefined (has been removed)
    }
    
    if ( ! this.state.some_old_key) {
        // key is undefined (has been removed)
    } else {
        // work with key
    }
    

    在 JSX 中:

    render() {
        return <div>
            { this.state.some_old_key ? "The state remains" : "The state is gone" }
        </div>
    }
    

    最后,要“替换”状态,只需将新状态对象与已为undefined 的旧状态的副本结合起来,并将其设置为状态:

    const new_state = {new_key1: "value1", new_key2: "value2"};
    const state = this.state;
    
    for (const old_key of Object.keys(state))
        state[old_key] = undefined;
    
    for (const new_key of Object.keys(new_state))
        state[new_key] = new_state[new_key];
    
    this.setState(state);
    

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 1970-01-01
      • 2016-03-15
      • 2014-11-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多