AngularJS转React的localStorage代码出现Uncaught TypeError错误
问题:React改写AngularJS localStorage代码时出现绑定错误
我有一段可正常实现localStorage数据读写与更新的AngularJS代码,尝试改写为React代码时,先出现“unexpected token”错误,调整后又出现“Uncaught TypeError: Cannot read properties of undefined (reading 'bind')”错误。
原AngularJS代码
<script> var app = angular.module('myapp', []); app.controller('MainCtrl', function($scope) { //初始化时调用,若localStorage中有数组则读取 $scope.checkAndInitiateFromLocalStorage = function() { var readArrayStr = localStorage.getItem('messagingArray'); if (readArrayStr && readArrayStr.length > 0) { $scope.arr = JSON.parse(readArrayStr); } else { $scope.arr = [{ name: "user1" }, { name: "user2" }, { name: "user3" }, { name: "user4" } ]; } } //每次更新时调用,将最新状态存入localStorage $scope.updateLocalStorage = function() { localStorage.setItem('messagingArray', JSON.stringify($scope.arr)); /* console.log("updated local storage !!"); */ } $scope.checkAndInitiateFromLocalStorage(); }); </script>
调整后的React代码
<script src="react.min.js"></script> <script src="react-dom.min.js"></script> <script src="browser.min.js"></script> <div id="app"></div> <script type="text/babel"> class Application extends React.Component { constructor(props) { super(props); //初始化时调用,若localStorage中有数组则读取 //const checkAndInitiateFromLocalStorage () { const checkAndInitiateFromLocalStorage = () => { var readArrayStr = localStorage.getItem('messagingArray'); if (readArrayStr && readArrayStr.length > 0) { this.state.arr = JSON.parse(readArrayStr); } else { this.state = { arr: [ { name: "user1"}, { name: "user2"}, { name: "user3"}, { name: "user4"} ], }; } } this.checkAndInitiateFromLocalStorage = this.checkAndInitiateFromLocalStorage.bind(this); this.updateLocalStorage = this.updateLocalStorage.bind(this); } //每次更新时调用,将最新状态存入localStorage updateLocalStorage() { localStorage.setItem('messagingArray', JSON.stringify(this.state.arr)); }; componentDidMount() { this.checkAndInitiateFromLocalStorage(); this.updateLocalStorage(); } render() { return ( <div> <h3>Display Data</h3> <ul> {this.state.arr.map((obj, i) => ( <li key={i}> {obj.name} - {obj.name} </li> ))} </ul> </div> ); } } ReactDOM.render(<Application />, document.getElementById('app')); </script>
最新报错信息
Uncaught TypeError: Cannot read properties of undefined (reading 'bind') at new Application (eval at transform.run
错误原因与修复方案
核心错误点
- 类方法定义错误:你在
constructor里用const定义了局部函数checkAndInitiateFromLocalStorage,它不是类的属性,所以this.checkAndInitiateFromLocalStorage是undefined,调用bind自然报错。 - 直接修改state:React中不能直接赋值
this.state.arr,必须通过this.setState更新状态。 - state初始化逻辑错误:不能在条件分支里直接赋值
this.state,应该先计算好初始值再统一初始化。
修正后的完整React代码
<script src="react.min.js"></script> <script src="react-dom.min.js"></script> <script src="browser.min.js"></script> <div id="app"></div> <script type="text/babel"> class Application extends React.Component { constructor(props) { super(props); // 初始化时直接计算state的初始值 this.state = this.checkAndInitiateFromLocalStorage(); // 绑定类方法的this指向 this.updateLocalStorage = this.updateLocalStorage.bind(this); } // 读取localStorage或返回默认数组,返回状态对象 checkAndInitiateFromLocalStorage() { const readArrayStr = localStorage.getItem('messagingArray'); if (readArrayStr && readArrayStr.length > 0) { return { arr: JSON.parse(readArrayStr) }; } else { return { arr: [ { name: "user1" }, { name: "user2" }, { name: "user3" }, { name: "user4" } ] }; } } // 将当前state存入localStorage updateLocalStorage() { localStorage.setItem('messagingArray', JSON.stringify(this.state.arr)); } componentDidMount() { // 组件挂载后更新一次localStorage this.updateLocalStorage(); } render() { return ( <div> <h3>Display Data</h3> <ul> {this.state.arr.map((obj, i) => ( <li key={i}> {obj.name} </li> ))} </ul> </div> ); } } ReactDOM.render(<Application />, document.getElementById('app')); </script>
关键修改说明
- 将
checkAndInitiateFromLocalStorage改为类方法,直接返回初始化的state对象,在constructor里直接赋值给this.state。 - 移除了对不存在的局部函数的bind操作,只绑定
updateLocalStorage方法(也可以用箭头函数定义该方法,省去bind步骤)。 - 去掉了render里重复的
{obj.name} - {obj.name},保留一个即可。 - 确保state初始化逻辑清晰,符合React的状态管理规范。
内容的提问来源于stack exchange,提问作者Nancy Moore
相关产品推荐
相关产品推荐

