在React + ES6中如何重置初始状态

17

我有一个类,如下所示的ElementBuilder,当用户保存他们构建的Element时,我希望状态重置为以下值。

在这个类中,我有一些函数,它们改变titlesizecolor的状态,但是我没有提供这些函数。

在ES 5中,我会在我的类上拥有一个getInitialState函数,并且可以在函数中调用this.getInitialState()

这个元素在我的应用程序中存活了一个已登录用户的生命周期,我希望默认值始终相同,无论过去的使用情况如何。

如何在不编写设置默认值对象的函数的情况下实现这一点(或者也许这就是答案)?谢谢!

class ElementBuilder extends Component {
    constructor(props) {
        super(props);

        this.state = {
            title: 'Testing,
            size: 100,
            color: '#4d96ce',
        };
    }

    resetBuilder() {
        this.setState({ this.getInitialState() });
    }
}

3
你可以在类外定义一个常量,并赋初值。然后在类内用它来初始化状态,并在任何时候重置状态。 - Crysfel
为了实现强大的状态管理,请查看redux。使用redux,您可以轻松地执行各种操作,例如撤消、重做和时间旅行。 - sachgits
4个回答

28

您可以使用 getter 函数:

class ElementBuilder extends Component {
  constructor(props) {
    super(props);

    this.state = this.initialState;
  }

  get initialState() {
    return {
      title: 'Testing',
      size: 100,
      color: '#4d96ce',
    };
  }

  resetBuilder() {
    this.setState(this.initialState);
  }
}

或者只是一个变量:

constructor(props) {
  super(props);

  this.initialState = {
    title: 'Testing',
    size: 100,
    color: '#4d96ce',
  };
  this.state = this.initialState;
}

1
一个 getter 函数仍然是一个函数 ;) - Felix Kling
@FelixKling 哦,我错过了“不写函数”的部分 :) 但第二个选项看起来不错。 - quotesBro
这很好。谢谢Mikhail和Felix! - Zack Shapiro
2
仅供参考,我认为在构造函数中,您应该调用this.getInitialState而不是this.initialState,并且在getInitialState函数中,您应该使用this.setState而不是this.state。 - blarg
1
resetBuilder函数中的代码应该是this.setState(this.initialState);吗? - Bobort
显示剩余2条评论

4
使用提议的类字段,您可以做如下操作:
class ElementBuilder extends Component {
    static initialState = {
        title: 'Testing',
        size: 100,
        color: '#4d96ce'
    }
    
    constructor(props) {
        super(props)

        this.state = ElementBuilder.initialState
    }

    resetBuilder() {
        this.setState(ElementBuilder.initialState)
    }
}

2

由于初始状态似乎不依赖于任何特定实例,因此只需在类外定义该值:

const initialState = {...};

class ElementBuilder extends Component {
    constructor(props) {
        super(props);

        this.state = initialState;
    }

    resetBuilder() {
        this.setState(initialState);
    }
}

为什么我们将initialState设置为一个类而不是一个变量? - Fellow Stranger
@FelixKling:为什么要使用this.setState(initialState)这种语法,而不是使用this.setState({ initialState })这种语法。你能否请稍微解释一下原因。 - SakthiSureshAnand
1
@SakthiSureshAnand: this.setState({intialState})this.setState({intialState: initalState}) 是一样的,即状态最终只有一个条目 initialState。这不是我们想要的。initialState 的每个属性都应该是状态的一部分。出于同样的原因,我们使用 this.state = initialState; 而不是 this.state = {initialState}; - Felix Kling
初始化状态后,当我更新状态时,它也会更新常量对象。 - Jay
@Jay:那就创建一个副本。根据结构,浅拷贝可能已经足够了。this.state = {...initialState}; - Felix Kling
如何从此组件或功能组件外部调用restBuilder()函数。 - Manoj Sharma

0
使用高阶组件来清除组件状态(重新渲染)
例子Element.jsx:
// Target ----- //

class Element extends Component {

  constructor(props){
    super(props)
    const {
        initState = {}
    } = props
    this.state = {initState}
  }

  render() {
    return (
        <div className="element-x">
            {...}
        </div>
    )
  }
}

// Target Manager ----- //

class ElementMgr extends Component {

    constructor(props){
        super(props)
        const {
            hash = 0
        } = props
        this.state = {
            hash, // hash is a post.id 
            load: false
        }
    }

    render() {
        const {load} = this.state
        if (load) {
            return (<div className="element-x"/>)
        } else {
            return (<Element {...this.props}/>)
        }
    }

    componentWillReceiveProps(nextProps) {
        const {hash = 0} = nextProps
        if (hash !== this.state.hash) {
            this.setState({load:true})
            setTimeout(() => this.setState({
                hash,
                load:false
            }),0)
        }
    }
}

export default ElementMgr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接