React JS:this.setState 和 JSON.parse
Posted
技术标签:
【中文标题】React JS:this.setState 和 JSON.parse【英文标题】:React JS : this.setState and JSON.parse 【发布时间】:2018-07-21 20:50:57 【问题描述】:我有一个问题,我不知道如何解决它。我正在向我的 api 发出请求,它以这样的对象响应:
"_id":"5a806648300caf0072c7254a","mail":"email@email.com"
我想将邮件打印到我的反应组件。在我的“componentDidMount()”函数中,我收到了邮件,所以我的 api 没有问题。但是当我想设置我的“用户”变量的状态时,我无法在我的组件中打印该变量......它说它是未定义的。
这是我的代码:
class UserList extends Component
constructor(props)
super(props);
this.state = users:[]
componentDidMount()
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
this.setState(users: JSON.parse(res));
//Here I can log the mail
console.log(this.state.users[0].mail);
)
render()
return (
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
//Here it is 'undefined'
<td>this.state.users[0].mail</td>
</tr>
</tbody>
</table>
);
感谢您的帮助!
【问题讨论】:
【参考方案1】:在上述情况下,问题在于理解 React 的组件生命周期。
请查看reference。
ComponentDidMount 在渲染发生后发生。
层次结构将是 1.构造函数 2.componentWillMount 3.渲染 4.componentDidMount
如果代码被修改为用 ComponentWillMount 替换 ComponentDidMount
componentWillMount()
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
this.setState(users: JSON.parse(res));
//Here I can log the mail
console.log(this.state.users.mail);
)
如果 api 工作正常,它将提供数据。
但是等待来自 api 的响应是一个对象,并且用数组初始化状态在概念上也是不正确的,我认为是这样。
由于我在 Typescript 中工作的大部分项目,状态初始化对我来说很重要。
constructor(props)
super(props);
this.state = users:
mail: ''
个人偏好是检查用户状态是否未定义,这肯定不会让您导致任何未定义或错误。
【讨论】:
【参考方案2】:您不应直接使用异步操作中的值。
由于componentDidMount()中的GetData
是异步函数,所以获取数据需要一些时间。所以在初始渲染中,user
的状态为空。
最好在获取数据之前使用加载指示器,并仅在接收到数据时显示数据。
你可以如下使用。
class UserList extends Component
constructor(props)
super(props);
this.state = users:[],
loading: false
componentDidMount()
//here my function that store the response from my api
this.setState(loading: true);
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
this.setState(users: JSON.parse(res), loading: false);
//Here I can log the mail
console.log(this.state.users[0].mail);
)
render()
if(this.state.loading)
return (<div> Loading... </div>)
return (
<div>
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
this.state.users.length > 0 &&
<tr>
<td>this.state.users[0].mail || ''</td>
</tr>
</tbody>
</table>
</div>
);
使用可以使用map循环如下
this.state.users.length > 0 && this.state.users.map(user =>
return(
<tr>
<td>user.mail || ''</td>
</tr>)
【讨论】:
【参考方案3】:React 安装组件生命周期是:
构造函数 组件WillMount 渲染 componentDidMount在此处查看更多信息:https://reactjs.org/docs/react-component.html#mounting
当你的组件挂载时 this.state.users 是一个空数组。
你可以改变渲染方法:
class UserList extends Component
constructor(props)
super(props);
this.state = users:[]
componentDidMount()
//here my function that store the response from my api
GetData('http://localhost:3333/users', 'username=admin',
(res) =>
// After setState react runs updating lifecycle methods (https://reactjs.org/docs/react-component.html#updating)
this.setState(users: JSON.parse(res));
//Here I can log the mail
console.log(this.state.users[0].mail);
)
render()
// if users are not loaded, we return null from render function
if (this.state.users.length === 0)
return null;
return (
<table>
<thead>
<tr>
<th>EMAIL</th>
</tr>
</thead>
<tbody>
<tr>
<td>this.state.users[0].mail</td>
</tr>
</tbody>
</table>
);
【讨论】:
我是如何使用 fetch 的? @SupunAbesekara 您可以将 GetData 替换为 window.fetch 并使用承诺链,例如:window.fetch(url, data).then(result => result.json()).then(json => this.setState(users: json.users);
以上是关于React JS:this.setState 和 JSON.parse的主要内容,如果未能解决你的问题,请参考以下文章
如何在 React JS 中的 css 转换结束后使用 setState?
如何使用 usestate 和 setstate 而不是 this.setState 使用 react 和 typescript?