javascript - 尝试将映射的 json 数据传递给状态时超出最大更新深度
问题描述
TLDR:如何将已映射的 json 数组传递回状态。我希望喜欢在一个州内。
例如像这样调用
<Like like={id} likes={this.state.likes} />
不像这样
<Like like={id} likes={Likes.length} />
我需要添加一个计数器来支持点击计数,这就是为什么这需要动态支持计数。
这是数组的可视化表示。
我这样做是为了在 PostList.js 中获取它
{this.getLikes(post.Likes)}
在我这样做的功能内
getLikes = (count) => {
const myLikes = count.forEach( (like) => like.length);
this.setState({
likes: myLikes
})
}
状态喜欢将在名为 myLikes 的道具中传递给 postItem 组件。
myLikes={this.state.likes}
在PostItem.js 中
它将被这样引用
<Like like={id} likes={myLikes} />
但是得到这个错误。
超过最大更新深度。当组件在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState 时,可能会发生这种情况。React 限制了嵌套更新的数量以防止无限循环。
这是详细的代码
PostList.js
import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import {connect} from 'react-redux';
import PostItem from './PostItem';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
}
}
class PostList extends Component{
constructor(props){
super(props);
this.state ={
title: '',
likes:[]
}
}
getLikes = (count) => {
const myLikes = count.forEach( (like) => like.length);
this.setState({
likes: myLikes
})
}
render(){
const {posts} = this.props;
return (
<div>
{posts.map((post, i) => (
<Paper key={post.id} style={Styles.myPaper}>
{this.getLikes(post.Likes)}
{/* {...post} prevents us from writing all of the properties out */}
<PostItem
myLikes={this.state.likes}
myTitle={this.state.title}
editChange={this.onChange}
editForm={this.formEditing}
isEditing={this.props.isEditingId === post.id}
removePost={this.removePost}
{...post}
/>
</Paper>
))}
</div>
)
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(PostList);
PostItem.js
import React, { Component } from 'react';
import Paper from '@material-ui/core/Paper';
import Button from '@material-ui/core/Button';
import Typography from '@material-ui/core/Typography';
import moment from 'moment';
import Editable from './Editable';
import {connect} from 'react-redux';
import {UpdatePost, postLike, getCount} from '../actions/';
import Like from './Like';
import Axios from '../Axios';
const Styles = {
myPaper: {
margin: '20px 0px',
padding: '20px'
},
button:{
marginRight:'30px'
}
}
class PostItem extends Component{
constructor(props){
super(props);
this.state = {
disabled: false,
myId: 0,
likes:0
}
}
componentWillMount(){
}
onUpdate = (id, title) => () => {
// we need the id so expres knows what post to update, and the title being that only editing the title.
if(this.props.myTitle !== null){
const creds = {
id, title
}
this.props.UpdatePost(creds);
}
}
render(){
const {title, id, userId, removePost, createdAt, post_content, username, editForm, isEditing, editChange, myTitle, postUpdate, Likes, clickLike, myLikes} = this.props
return(
<div>
<Typography variant="h6" component="h3">
{/* if else teneray operator */}
{isEditing ? (
<Editable editField={myTitle ? myTitle : title} editChange={editChange}/>
): (
<div>
{title}
</div>
)}
</Typography>
<Typography component={'span'} variant={'body2'}>
{post_content}
<h5>by: {username} </h5>
{/* component span cancels out the cant be a decedent of error */}
<Typography component={'span'} variant={'body2'} color="textSecondary">{moment(createdAt).calendar()}</Typography>
{/* gets like counts */}
<Like like={id} likes={myLikes} />
</Typography>
{!isEditing ? (
<Button variant="outlined" type="submit" onClick={editForm(id)}>
Edit
</Button>
):(
// pass id, and myTitle which as we remember myTitle is the new value when updating the title
<div>
<Button
disabled={myTitle.length <= 3}
variant="outlined"
onClick={this.onUpdate(id, myTitle)}>
Update
</Button>
<Button
variant="outlined"
style={{marginLeft: '0.7%'}}
onClick={editForm(null)}>
Close
</Button>
</div>
)}
{!isEditing && (
<Button
style={{marginLeft: '0.7%'}}
variant="outlined"
color="primary"
type="submit"
onClick={removePost(id)}>
Remove
</Button>
)}
</div>
)
}
}
const mapStateToProps = (state) => ({
})
const mapDispatchToProps = (dispatch) => ({
});
export default connect(mapStateToProps, mapDispatchToProps)(PostItem);
还有更多信息
Posts.js
import React, { Component } from 'react';
import PostList from './PostList';
import {connect} from 'react-redux';
import { withRouter, Redirect} from 'react-router-dom';
import {GetPosts} from '../actions/';
const Styles = {
myPaper:{
margin: '20px 0px',
padding:'20px'
}
,
wrapper:{
padding:'0px 60px'
}
}
class Posts extends Component {
state = {
posts: [],
loading: true,
isEditing: false,
}
async componentWillMount(){
await this.props.GetPosts();
const thesePosts = await this.props.myPosts
const myPosts2 = await thesePosts
this.setState({
posts: myPosts2,
loading:false
})
}
render() {
const {loading} = this.state;
const { myPosts} = this.props
if (!this.props.isAuthenticated) {
return (<Redirect to='/signIn' />);
}
if(loading){
return "loading..."
}
return (
<div className="App" style={Styles.wrapper}>
<h1> Posts </h1>
<PostList posts={this.state.posts}/>
</div>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.user.isAuthenticated,
myPosts: state.post.posts
})
const mapDispatchToProps = (dispatch, state) => ({
GetPosts: () => dispatch( GetPosts())
});
export default withRouter(connect(mapStateToProps,mapDispatchToProps)(Posts));
解决方案
推荐阅读
- flutter - Flutter:第一次第二页传入参数的值为null
- java - Maven - 增加 JVM 的内存
- flutter - Flutter:从 ListTile 重建 ListView
- node.js - Angular:意外值“CdkScrollableModule”中的错误
- javascript - js中的if语句出现语法错误
- influxdb - InfluxDB 2.0 中的存储桶、度量和保留策略之间的逻辑联系是什么?
- excel - 尝试使用动态范围执行四分位数分析
- android - 如何让飞镖打印未处理的异常到文件而不是标准错误?
- sql-server - 全新安装 SQL Server 2019 开发人员版后未启动 SQL Server 实例
- python - 检索 GraphQL Introspection Schema 作为 http 响应