Javascript 使用本地存储持久化状态不会在react类组件中保存视图类型的状态数据

Javascript 使用本地存储持久化状态不会在react类组件中保存视图类型的状态数据,javascript,reactjs,react-native,cookies,local-storage,Javascript,Reactjs,React Native,Cookies,Local Storage,我试图保存listView的状态,它是我的类组件中的一个布尔值。listView为true时的默认值。如果为true,它将呈现listView,如果为false,则不会呈现listView。我已经试着研究过了。我发现,使用react钩子很容易做到这一点,但是,使用类组件实现这一点的示例太少了。我在类组件中看到的几个例子让我尝试并实现了一些类似于我的代码的东西。但是,仍然在选择另一个视图并导航离开页面或页面刷新后,该状态不会持续。请参阅下文: 实施前: constructor(props) {

我试图保存listView的状态,它是我的类组件中的一个布尔值。listView为true时的默认值。如果为true,它将呈现listView,如果为false,则不会呈现listView。我已经试着研究过了。我发现,使用react钩子很容易做到这一点,但是,使用类组件实现这一点的示例太少了。我在类组件中看到的几个例子让我尝试并实现了一些类似于我的代码的东西。但是,仍然在选择另一个视图并导航离开页面或页面刷新后,该状态不会持续。请参阅下文:

实施前:

constructor(props) {
    super(props);
    this.state = {
      listView: true,
    };
  }



<ToggleButtonGroup className={classes.toggleButtonContainer} exclusive orientation="horizontal">
       <ToggleButton className={listView ? classes.selectedToggleButton : '' } selected={listView} onClick={() => this.setState({ listView: true })} value="list" aria-label="list">
         <Icon fontSize="large" color="default">view_list</Icon>
                </ToggleButton>
                <ToggleButton className={!listView ? classes.selectedToggleButton : '' } selected={!listView} onClick={() => this.setState({ listView: false })} value="module" aria-label="module">
                  <Icon fontSize="large" color="default">view_module</Icon>
                </ToggleButton>
         </ToggleButtonGroup>
constructor(props) {
   super(props);
   this.state = {
      listView: JSON.parse(localStorage.getItem('listView')) || []
    }
  }

 renderListView = (selection) => {
      ...

      this.setState({
        listView: selection
      },() => {
        localStorage.setItem('listView', JSON.stringify(this.state.listView))
      });
    }


 <ToggleButtonGroup className={classes.toggleButtonContainer} exclusive orientation="horizontal">
                <ToggleButton className={listView ? classes.selectedToggleButton : '' } selected={listView} onClick={() => this.renderListView(true)} value="list" aria-label="list">
                  <Icon fontSize="large" color="default">view_list</Icon>
                </ToggleButton>
                <ToggleButton className={!listView ? classes.selectedToggleButton : '' } selected={!listView} onClick={() => this.renderListView(false)} value="module" aria-label="module">
                  <Icon fontSize="large" color="default">view_module</Icon>
                </ToggleButton>
              </ToggleButtonGroup>
构造函数(道具){
超级(道具);
此.state={
listView:是的,
};
}
this.setState({listView:true})value=“list”aria label=“list”>
查看列表
this.setState({listView:false})value=“module”aria label=“module”>
视图单元
实施后:

constructor(props) {
    super(props);
    this.state = {
      listView: true,
    };
  }



<ToggleButtonGroup className={classes.toggleButtonContainer} exclusive orientation="horizontal">
       <ToggleButton className={listView ? classes.selectedToggleButton : '' } selected={listView} onClick={() => this.setState({ listView: true })} value="list" aria-label="list">
         <Icon fontSize="large" color="default">view_list</Icon>
                </ToggleButton>
                <ToggleButton className={!listView ? classes.selectedToggleButton : '' } selected={!listView} onClick={() => this.setState({ listView: false })} value="module" aria-label="module">
                  <Icon fontSize="large" color="default">view_module</Icon>
                </ToggleButton>
         </ToggleButtonGroup>
constructor(props) {
   super(props);
   this.state = {
      listView: JSON.parse(localStorage.getItem('listView')) || []
    }
  }

 renderListView = (selection) => {
      ...

      this.setState({
        listView: selection
      },() => {
        localStorage.setItem('listView', JSON.stringify(this.state.listView))
      });
    }


 <ToggleButtonGroup className={classes.toggleButtonContainer} exclusive orientation="horizontal">
                <ToggleButton className={listView ? classes.selectedToggleButton : '' } selected={listView} onClick={() => this.renderListView(true)} value="list" aria-label="list">
                  <Icon fontSize="large" color="default">view_list</Icon>
                </ToggleButton>
                <ToggleButton className={!listView ? classes.selectedToggleButton : '' } selected={!listView} onClick={() => this.renderListView(false)} value="module" aria-label="module">
                  <Icon fontSize="large" color="default">view_module</Icon>
                </ToggleButton>
              </ToggleButtonGroup>
构造函数(道具){
超级(道具);
此.state={
listView:JSON.parse(localStorage.getItem('listView'))| |[]
}
}
renderListView=(选择)=>{
...
这是我的国家({
列表视图:选择
},() => {
localStorage.setItem('listView',JSON.stringify(this.state.listView))
});
}
this.renderListView(true)}value=“list”aria label=“list”>
查看列表
this.renderListView(false)}value=“module”aria label=“module”>
视图单元
本地存储值正在切换,但在页面刷新后,状态仍将恢复为true

当我在本地存储中切换时,本地存储显示了另一个值


Ibsn完美地诊断了您的问题

JavaScript在处理类型方面非常奇怪。每一个值都被认为是或,这取决于它们的计算结果是
true
还是
false

|
运算符返回第一个值(如果为“truthy”),返回第二个值(如果不是)

在您的情况下,第一个值可以有3个可能的值:
null
(如果您从未按下过按钮),以及
true
false
(如果您以前按下过按钮)

通常,
|
操作符可以很好地区分例如和对象以及
null
,但是在这里,
null
false
都是“falsy”,因此
false
值被空数组
[]
替换,这是“truthy”。这会导致忽略localStorage中的值

有几种方法可以解决这个问题。我建议的方法是显式检查localStorage中的值是否为
null

const storageValue = JSON.parse(localStorage.getItem("listView"));
this.state = {
    listView: storageValue !== null ? storageValue : true,
};

Ibsn完美地诊断了你的问题

JavaScript在处理类型方面非常奇怪。每一个值都被认为是或,这取决于它们的计算结果是
true
还是
false

|
运算符返回第一个值(如果为“truthy”),返回第二个值(如果不是)

在您的情况下,第一个值可以有3个可能的值:
null
(如果您从未按下过按钮),以及
true
false
(如果您以前按下过按钮)

通常,
|
操作符可以很好地区分例如和对象以及
null
,但是在这里,
null
false
都是“falsy”,因此
false
值被空数组
[]
替换,这是“truthy”。这会导致忽略localStorage中的值

有几种方法可以解决这个问题。我建议的方法是显式检查localStorage中的值是否为
null

const storageValue = JSON.parse(localStorage.getItem("listView"));
this.state = {
    listView: storageValue !== null ? storageValue : true,
};

欢迎来到Stackoverflow!您可以在按下按钮后检查开发工具中是否设置了localStorage中的值吗?谢谢,当然可以!让我检查是的,当我切换视图时,它会切换。我看不到您的代码有任何立即的错误。能否在构造函数的末尾添加一个
console.log(this.state)
?也许这会让问题更清楚。猜猜看,既然listView是一个布尔值,为什么要这样设置初始状态:
listView:JSON.parse(localStorage.getItem('listView'))|【】
?如果您在localStorage中有
listView:false
,这将导致在每次刷新时将状态设置为空数组,然后将计算TruthyHelpCome to Stackoverflow!您可以在按下按钮后检查开发工具中是否设置了localStorage中的值吗?谢谢,当然可以!让我检查是的,当我切换视图时,它会切换。我看不到您的代码有任何立即的错误。能否在构造函数的末尾添加一个
console.log(this.state)
?也许这会让问题更清楚。猜猜看,既然listView是一个布尔值,为什么要这样设置初始状态:
listView:JSON.parse(localStorage.getItem('listView'))|【】
?如果在localStorage中有
listView:false
,这将导致在每次刷新时将状态设置为空数组,然后将计算truthy