Updating State Breaks Child Prop Component - reactjs

I am still trying to get a handle on parent-child data sharing and have an issue where my stateful component has an array of objects that display correctly within my child prop components via componentWillReceiveProps(), but when I trigger my updateCommentsFunc() function, which is triggered by a child component form, the POST is called and value is appended to the array, but I get an undefined error from my child component that demonstrates that the data isn't flowing post state update.
Am I using the wrong method? Should I add something to my updateCommentsFunc()?
Here is the console error:
Uncaught TypeError: Cannot read property 'picture' of undefined
at Comment (comment.js?2fa6:15)
at mountIndeterminateComponent (react-dom.development.js?cada:10400)
at beginWork (react-dom.development.js?cada:10601)
at performUnitOfWork (react-dom.development.js?cada:12573)
at workLoop (react-dom.development.js?cada:12682)
at HTMLUnknownElement.callCallback (react-dom.development.js?cada:1299)
at Object.invokeGuardedCallbackDev (react-dom.development.js?cada:1338)
at invokeGuardedCallback (react-dom.development.js?cada:1195)
at performWork (react-dom.development.js?cada:12800)
at scheduleUpdateImpl (react-dom.development.js?cada:13185)
Triggered at line:
<img src={props.user.picture} className="comment__record-profile"/>
This is the parent component which is fed an object that has its nested array mapped and stored in an array in the state:
//Loop through JSON and create Comment and Comment Container Component
class CommentFeed extends React.Component {
constructor(props){
super(props);
this.state = {
comments: []
};
this.updateCommentsFunc = this.updateCommentsFunc.bind(this);
}
//Load Array to component
componentWillReceiveProps(nextProps){
let commentArr = [];
nextProps.comments.map((comment) => {
comment.comment_comments.map((comment) => {
commentArr.push(comment);
})
})
this.setState({comments: commentArr});
}
//Append new POST value to commentArr
updateCommentsFunc(newComments){
var updatedCommentArr = this.state.comments.slice();
updatedCommentArr.push(newComments)
this.setState({comments: updatedCommentArr});
}
render(){
return (
<div>
{
this.props.comments.map((comment, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 comment-card">
<CommentCard {...comment} key={comment.commentIdHash} user={this.props.user} />
<Comments comments={this.state.comments} key={index} commentId={comment.commentIdHash} csrf={this.props.csrf} updateComments={this.updateCommentsFunc}/>
</div>
</div>
);
})
}
</div>
);
}
}
Here is the child component split into a form and displayed comments:
//Blog Comment - Container
export default class Comments extends React.Component {
render() {
return (
<div className="blog-comment-container">
<CommentForm updateComments={this.props.updateComments} blogId={this.props.blogId} csrf={this.props.csrf}/>
{ this.props.comments.map((comment, i) =>
<AttachedComment commentObj={comment} blogComponentId={this.props.blogId}/>
)}
</div>
);
}
}
Here is the form calling this.props.updateComments() with the returned JSON data from the POST:
class CommentForm extends React.Component {
constructor(props){
super(props);
this.state = {
value: ''
};
this.postComment = this.postComment.bind(this);
this.onChange = this.onChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
postComment(comment, blogId, csrfToken) {
var body = { comment: comment };
var route = 'http://localhost:3000/app/blog/' + blogId + '/comment';
fetch(route,
{
method: 'POST',
body: JSON.stringify(body),
headers: {
'X-CSRF-Token': csrfToken,
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(res => {
return res.json();
})
.then(data => {
this.props.updateComments(data)
})
.catch(err => {
console.log(err);
});
}
onChange(e){
this.setState({
value: e.target.value
});
}
handleSubmit(e){
e.preventDefault();
this.postComment(this.state.value, this.props.blogId, this.props.csrf);
}
render(){
return (
<div className="blog-comment__form">
<div className="row">
<div className="col-md-12">
<label>Comment:</label>
</div>
</div>
<div className="row">
<form action={"/app/blog/" + this.props.blogId + "/comment"} method="post" onSubmit={this.handleSubmit}>
<input type="hidden" name="_csrf" value={this.props.csrf}/>
<div className="col-md-9">
<textarea name="comment" className="blog-comment__form-text-area" onChange={e => this.setState({ value: e.target.value })} value={this.state.value}></textarea>
</div>
<div className="col-md-3">
<button type="submit" className="blog-comment__form-button" disabled={!this.state.value}>Comment</button>
</div>
</form>
</div>
</div>
)
}
}
Here is the conditional that checks to see if the nested array Id matches the id from the fed object at the parent:
const AttachedComment = props => {
if(props.commentObj.blogIdHash == props.blogComponentId){
return (
<Comment {...props.commentObj} key={props.commentObj.blogCommentId}/>
)
} else {
return null;
}
}
Finally, if that returns TRUE then the component where the error appeared is rendered:
const Comment = props => {
return (
<div className="comment-comment__record">
<div className="row">
<div className="col-md-12">
<div className="comment-comment__meta">
<div className="row">
<div className="col-md-6">
<img src={props.user.picture} className="comment-comment__record-profile"/>
</div>
<div className="col-md-6">
</div>
</div>
</div>
<h5>{props.user_id}</h5>
<h4>{props.comment}</h4>
<h3>{props.synotate_user.fullNameSlug}</h3>
</div>
</div>
</div>
)
}

Related

Array has duplicated records when using checkboxes to populate an array using React

I have trouble with simple task of adding elements selected in checkboxes to an array in component state. It seems like the push method for state.toppings (Editor.js) is invoked twice for each checkbox click, even though console.log shows that updateFormValueCheck method is invoked once per click. Can anyone help?
This is App.js
import React, { Component } from "react";
import { Editor } from "./Editor";
import { Display } from "./Display";
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
formData: {}
}
}
submitData = (newData) => {
console.log("newData", newData)
this.setState({ formData: newData });
}
render() {
return <div className="container-fluid">
<div className="row p-2">
<div className="col-6">
<Editor submit={this.submitData} />
</div>
<div className="col-6">
<Display data={this.state.formData} />
</div>
</div>
</div>
}
}
This is Editor.js
import React, { Component } from "react";
export class Editor extends Component {
constructor(props) {
super(props);
this.state = {
toppings: ["Strawberries"]
}
this.toppings = ["Sprinkles", "Fudge Sauce",
"Strawberries", "Maple Syrup"]
}
updateFormValueCheck = (event) => {
event.persist();
this.setState(state => {
if (event.target.checked) {
state.toppings.push(event.target.name);
} else {
let index = state.toppings.indexOf(event.target.name);
state.toppings.splice(index, 1);
}
}, () => this.props.submit(this.state));
}
render() {
return <div className="h5 bg-info text-white p-2">
<div className="form-group">
<label>Ice Cream Toppings</label>
{this.toppings.map(top =>
<div className="form-check" key={top}>
<input className="form-check-input"
type="checkbox" name={top}
value={this.state[top]}
checked={this.state.toppings.indexOf(top) > -1}
onChange={this.updateFormValueCheck} />
<label className="form-check-label">{top}</label>
</div>
)}
</div>
</div>
}
}
This is Display.js
import React, { Component } from "react";
export class Display extends Component {
formatValue = (data) => Array.isArray(data)
? data.join(", ") : data.toString();
render() {
let keys = Object.keys(this.props.data);
if (keys.length === 0) {
return <div className="h5 bg-secondary p-2 text-white">
No Data
</div>
} else {
return <div className="container-fluid bg-secondary p-2">
{keys.map(key =>
<div key={key} className="row h5 text-white">
<div className="col">{key}:</div>
<div className="col">
{this.formatValue(this.props.data[key])}
</div>
</div>
)}
</div>
}
}
}
The output is:
You cannot directly mutate this.state, it can only be done using this.setState. For more info. refer this: Why can't I directly modify a component's state, really?
Therefore, you need to update your Editor component as follows.
componentDidMount is used to display the initial state during the initial rendering. Then componentDidUpdate is used to render the state changes through display component whenever it's updated.
import React, { Component } from "react";
export class Editor extends Component {
constructor(props) {
super(props);
this.state = {
toppings: ["Strawberries"],
};
this.toppings = ["Sprinkles", "Fudge Sauce", "Strawberries", "Maple Syrup"];
}
updateFormValueCheck = (event) => {
event.persist();
let data;
if (event.target.checked) {
data = [...this.state.toppings, event.target.name];
} else {
const index = this.state.toppings.indexOf(event.target.name);
const temp = [...this.state.toppings];
temp.splice(index, 1);
data = temp;
}
this.setState({
toppings: data,
});
};
componentDidMount() {
this.props.submit(this.state.toppings);
}
componentDidUpdate(prevPros, prevState) {
if (prevState.toppings !== this.state.toppings) {
this.props.submit(this.state.toppings);
}
}
render() {
console.log(this.state);
return (
<div className="h5 bg-info text-white p-2">
<div className="form-group">
<label>Ice Cream Toppings</label>
{this.toppings.map((top) => (
<div className="form-check" key={top}>
<input
className="form-check-input"
type="checkbox"
name={top}
value={this.state[top]}
checked={this.state.toppings.indexOf(top) > -1}
onChange={this.updateFormValueCheck}
/>
<label className="form-check-label">{top}</label>
</div>
))}
</div>
</div>
);
}
}
Hope this would be helpful to solve your issue.

ReactJS select value from json array

So I'm trying to get some data from my api and then select that data and send it to the other api, but I can't figure it out how to select the data.
import React, { Component } from 'react'
import Dropdown from 'react-dropdown'
import 'react-dropdown/style.css'
class Testas extends Component {
constructor(props){
super(props);
this.state = {
}
}
componentDidMount() {
const headers = {
'Authorization': 'Bearer ',''
};
fetch(`https://spiceworks/api/printserver/printers`,{ headers }
)
.then(res => res.json())
.then(json => {
this.setState({
isLoaded: true,
items: json.printers,
})
});
}
render() {
const { items } = this.state
const type = ['test', 'python', 'web', 'all']
const amount = [1,2,3,4,5,6,7,8,9,10]
return (
<div className="content">
<form>
<div className="row">
<div className="col-sm">
<div className="card">
<div className="card-body">
<h3 className="card-title">Printer Test</h3>
<Dropdown className="drop" options={this.state.items} placeholder="Pasirinkti printerį" />
<Dropdown className="drop2" options={type} placeholder="Būdas" />
<Dropdown className="drop2" options={amount} placeholder="Kiekis" />
Test
</div>
</div>
</div>
</div>
</form>
</div>
)
}
}
export default Testas
the data I recieve from api looks like this
{
"printers": [
"ZEB-SOFA15",
"ZEB-120",
"GDX-SOFUZ4",]}
i tried with e value onchange code but then I always get error that data.map is not a function.

How to resolve React state updating but not pushing values to props?

I am fetching data from an API to build a page that will display recipes as a fun little app to add on to my "things I've built" list. I can run the fetch call and see that the state is updated in dev tools, but after adding a ternary operation to render this new data once the search is performed, the new state/data does not seem to pass into my child component props.
I've tried providing default values to the recipes prop
recipes={ this.state.results || {"id": 1, title: "test", "servings": "6", "readyInMinutes": 10}}
and I've tried setting isLoading in the callback of my setState call
this.setState({ results: resData.data.results},
() => { this.setState({isLoading: false});} )
I've been all over stack overflow and other resources trying just about anything i can find...I understand the setState is asynchronous and I've tried playing around with every solution I can find on google rephrasing this question over and over, and at this point I assume its some precise problem that I am just not noticing.
Main Component:
class CookingPage extends Component {
state = {
results: [],
isLoading: true,
}
isActive = true;
constructor(props) {
super(props);
}
// componentDidMount(){
// this.setState({
// isLoading: false
// });
// }
srchApi = e => {
e.preventDefault();
let validated = false;
let query = document.getElementById('search').value;
let cuisine = document.getElementById('cuisine').value;
let diet = document.getElementById('diet').value;
if(query){
validated = true;
}
if (!validated) {
//code to notify user of invalid search
return;
} else {
fetch('http://localhost/cooking', {
method: 'post',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
query: query,
cuisine: cuisine,
diet: diet
})
}).then(res => {
return res.json();
}).then(resData => {
if(this.isActive){
debugger;
this.setState({
results: resData.data.results,
isLoading: false
});
}
}).catch(err => {
if(this.isActive){
this.setState({isLoading: false});
}
});
}
}
componentWillUnmount() {
this.isActive = false;
}
render() {
return (
<div className='background'>
<div className="container">
<div className="row">
<div className="col-12">
<div className='container search-ctr'>
<Form>
<div className='row'>
<div className='col-4 plain-search'>
<Form.Group controlId='search'>
<Form.Label>Plain Search</Form.Label>
<Form.Control type='text' placeholder='Recipes...Nutrients...Ingredients...Just search!'></Form.Control>
</Form.Group>
</div>
<div className='col-4 col-cuisine'>
<Form.Group controlId='cuisine'>
<Form.Label>Cuisine</Form.Label>
<Form.Control type='text' placeholder='Italian, Mexican, etc..'></Form.Control>
</Form.Group>
</div>
<div className='col-4 col-diet'>
<Form.Group controlId='diet'>
<Form.Label>Diet</Form.Label>
<Form.Control type='text' placeholder='Vegetarian, Vegan, etc...'></Form.Control>
</Form.Group>
</div>
</div>
<div className='row'>
<div className='col-12'>
<button type="submit" className="btn btn-outline-light btnSearch" onClick={this.srchApi}>Search</button>
</div>
</div>
</Form>
</div>
</div>
</div>
<div className='row'>
<div className='col-12'>
{this.state.isLoading ? (<div></div>) :
<RecipeList
recipes={this.state.results}
onDetail={this.showDetailsHandler}
/>
}
</div>
</div>
</div>
</div>
);
}
}
export default CookingPage;
Child component:
const RecipeList = props => {
const mapRecipes = props.recipes.map(recipe => {
return(
<PreviewRecipe
key = {recipe.id}
className = "preview-recipe"
recipekey = {recipe.id}
recipeid = {recipe.id}
title = {recipe.title}
cookTime = {recipe.readyInMinutes}
servings = {recipe.servings}
onDetail = {props.onViewDetail}
/>
)
});
return (
<React.Fragment>
<div className = "recipe-list-ctr">
<h4 className = "recipe-list-title">Title</h4>
<h4 className = "recipe-list-servings">Servings</h4>
<h4 className = "recipe-list-img">Image</h4>
</div>
{mapRecipes}
</React.Fragment>
)
};
export default RecipeList;
I expect a list of RecipeList components to display on the page after being mapped from the props, however I get the error:
"TypeError: Cannot read property 'map' of undefined.
As I explained before, using dev tools and removing the isLoading:false from the setState call, I can see in dev tools that the state is updating to the data received from the API, so I am really unsure as to why it is not being passed through. My understanding of the life-cycle just might not be up to par yet, and I would appreciate and solutions or suggestions to help me debug and get back on the right track.
I've figured out the issue I believe. After days and hours of debugging, the issue came to be that my import statement for one of my components was importing from the wrong file. Thus it was rendering a component with props that were undefined.

How to make create/edit popup form component

I'm trying to make simple CRUD example using react.js as frontend.
I already have add/edit functionality done in a component,
but I want to call this component dynamically on click and show it as a popup or modal window on the same page without redirecting to another route.
Does anyone have experience with doing this using react.js?
This is my parent component code where I show a grid of items displaying cities:
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { Link, NavLink } from 'react-router-dom';
interface FetchNaseljeDataState {
nasList: NaseljeData[];
loading: boolean;
}
export class FetchNaselje extends React.Component<RouteComponentProps<{}>, FetchNaseljeDataState> {
constructor() {
super();
this.state = { nasList: [], loading: true };
fetch('api/Naselje/Index')
.then(response => response.json() as Promise<NaseljeData[]>)
.then(data => {
this.setState({ nasList: data, loading: false });
});
// This binding is necessary to make "this" work in the callback
this.handleDelete = this.handleDelete.bind(this);
this.handleEdit = this.handleEdit.bind(this);
}
public render() {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: this.renderNaseljeTable(this.state.nasList);
return <div>
<h1>Naselje Data</h1>
<p>This component demonstrates fetching Naselje data from the server.</p>
<p>
<Link to="/addnaselje">Create New</Link>
</p>
{contents}
</div>;
}
// Handle Delete request for an naselje
private handleDelete(id: number) {
if (!confirm("Do you want to delete naselje with Id: " + id))
return;
else {
fetch('api/Naselje/Delete/' + id, {
method: 'delete'
}).then(data => {
this.setState(
{
nasList: this.state.nasList.filter((rec) => {
return (rec.idnaselje != id);
})
});
});
}
}
private handleEdit(id: number) {
this.props.history.push("/naselje/edit/" + id);
}
// Returns the HTML table to the render() method.
private renderNaseljeTable(naseljeList: NaseljeData[]) {
return <table className='table'>
<thead>
<tr>
<th></th>
<th>ID Naselje</th>
<th>Naziv</th>
<th>Postanski Broj</th>
<th>Drzava</th>
</tr>
</thead>
<tbody>
{naseljeList.map(nas =>
<tr key={nas.idnaselje}>
<td></td>
<td>{nas.idnaselje}</td>
<td>{nas.naziv}</td>
<td>{nas.postanskiBroj}</td>
<td>{nas.drzava && nas.drzava.naziv}</td>
<td>
<a className="action" onClick={(id) => this.handleEdit(nas.idnaselje)}>Edit</a> |
<a className="action" onClick={(id) => this.handleDelete(nas.idnaselje)}>Delete</a>
</td>
</tr>
)}
</tbody>
</table>;
}
}
export class NaseljeData {
idnaselje: number = 0;
naziv: string = "";
postanskiBroj: string = "";
drzava: DrzavaData = { iddrzava: 0, naziv: ""};
drzavaid: number = 0;
}
export class DrzavaData {
iddrzava: number = 0;
naziv: string = "";
}
This is my child component that I want to dynamically show on create new link click:
import * as React from 'react';
import { RouteComponentProps } from 'react-router';
import { Link, NavLink } from 'react-router-dom';
import { NaseljeData } from './FetchNaselje';
import { DrzavaData } from './FetchNaselje';
interface AddNaseljeDataState {
title: string;
loading: boolean;
drzavaList: Array<any>;
nasData: NaseljeData;
drzavaId: number;
}
export class AddNaselje extends React.Component<RouteComponentProps<{}>, AddNaseljeDataState> {
constructor(props) {
super(props);
this.state = { title: "", loading: true, drzavaList: [], nasData: new NaseljeData, drzavaId: -1 };
fetch('api/Naselje/GetDrzavaList')
.then(response => response.json() as Promise<Array<any>>)
.then(data => {
this.setState({ drzavaList: data });
});
var nasid = this.props.match.params["nasid"];
// This will set state for Edit naselje
if (nasid > 0) {
fetch('api/Naselje/Details/' + nasid)
.then(response => response.json() as Promise<NaseljeData>)
.then(data => {
this.setState({ title: "Edit", loading: false, nasData: data });
});
}
// This will set state for Add naselje
else {
this.state = { title: "Create", loading: false, drzavaList: [], nasData: new NaseljeData, drzavaId: -1 };
}
// This binding is necessary to make "this" work in the callback
this.handleSave = this.handleSave.bind(this);
this.handleCancel = this.handleCancel.bind(this);
}
public render() {
let contents = this.state.loading
? <p><em>Loading...</em></p>
: this.renderCreateForm(this.state.drzavaList);
return <div>
<h1>{this.state.title}</h1>
<h3>Naselje</h3>
<hr />
{contents}
</div>;
}
// This will handle the submit form event.
private handleSave(event) {
event.preventDefault();
const data = new FormData(event.target);
// PUT request for Edit naselje.
if (this.state.nasData.idnaselje) {
fetch('api/Naselje/Edit', {
method: 'PUT',
body: data,
}).then((response) => response.json())
.then((responseJson) => {
this.props.history.push("/fetchnaselje");
})
}
// POST request for Add naselje.
else {
fetch('api/Naselje/Create', {
method: 'POST',
body: data,
}).then((response) => response.json())
.then((responseJson) => {
this.props.history.push("/fetchnaselje");
})
}
}
// This will handle Cancel button click event.
private handleCancel(e) {
e.preventDefault();
this.props.history.push("/fetchnaselje");
}
// Returns the HTML Form to the render() method.
private renderCreateForm(drzavaList: Array<any>) {
return (
<form onSubmit={this.handleSave} >
<div className="form-group row" >
<input type="hidden" name="idnaselje" value={this.state.nasData.idnaselje} />
</div>
< div className="form-group row" >
<label className=" control-label col-md-12" htmlFor="Naziv">Naziv</label>
<div className="col-md-4">
<input className="form-control" type="text" name="naziv" defaultValue={this.state.nasData.naziv} required />
</div>
</div >
<div className="form-group row">
<label className="control-label col-md-12" htmlFor="PostanskiBroj" >Postanski broj</label>
<div className="col-md-4">
<input className="form-control" name="PostanskiBroj" defaultValue={this.state.nasData.postanskiBroj} required />
</div>
</div>
<div className="form-group row">
<label className="control-label col-md-12" htmlFor="Drzava">Država</label>
<div className="col-md-4">
<select className="form-control" data-val="true" name="drzavaid" defaultValue={this.state.nasData.drzava ? this.state.nasData.drzava.naziv : ""} required>
<option value="">-- Odaberite Državu --</option>
{drzavaList.map(drzava =>
<option key={drzava.iddrzava} value={drzava.iddrzava}>{drzava.naziv}</option>
)}
</select>
</div>
</div >
<div className="form-group">
<button type="submit" className="btn btn-default">Save</button>
<button className="btn" onClick={this.handleCancel}>Cancel</button>
</div >
</form >
)
}
}
I'm assuming I'll have to make css for the create/edit component to make it look like a popup...
EDIT: I would appreciate if someone could make code example using my classes, thanks...
In the parent component set a state on click functionality, say for eg:
this.setState({display: true})
In the parent component render based on condition display child component, say for eg:
<div>{(this.state.display) ? <div><childComponent /></div> : ''}</div>
To display the child component in a modal/popup, put the component inside say a bootstrap or react-responsive-modal. For that, you have to install and import react-responsive-modal and then
In the render method,
return (
<div>
{this.state.toggleModal ? <div className="container">
<Modal open={this.state.toggleModal} onClose={this.onCloseModal} center>
<div className="header">
<h4>{Title}</h4>
</div>
<div className="body">
<div>
{this.state.toggleModal ? <someComponent /> : ''}
</div>
</div>
</Modal>
</div>
: null}
</div>
)
Have your popup component receive a prop from the parent that will tell it if it should be displayed or not, a simple boolean will do the trick. Then, when you want something to show the popup, just change that state in the parent.

Accessing Props Error in Stateful Child Component

I am trying to access the parent object within the stateful child component, but I can't seem to understand why the object is not found. This component was converted from stateless and worked fine, so I'm curious what broke post-conversion. Do I need to set an empty array within the state and then a function to setState with the prop?
Here is the error:
Uncaught ReferenceError: props is not defined
At line this.props.blogs.map((blog, index) => {
Here are the two components:
//GET /api/app and set to state
class BlogFeedContainer extends React.Component{
constructor(props, context) {
super(props, context);
this.state = this.context.data || window.__INITIAL_STATE__ || {blogs: []};
}
fetchList() {
fetch('http://localhost:3000/api/test')
.then(res => {
return res.json();
})
.then(data => {
console.log(data);
this.setState({ blogs: data.blog, user: data.user, csrf: data.csrfToken });
})
.catch(err => {
console.log(err);
});
}
componentDidMount() {
this.fetchList();
}
render() {
return (
<div className="container">
<h2>Comments List</h2>
<BlogFeed {...this.state} />
</div>
)
}
};
//Loop through JSON and create Blog and Comment Container Component
class BlogFeed extends React.Component {
constructor(props){
super(props);
this.state = {
comments: []
};
}
render(){
return (
<div>
{
this.props.blogs.map((blog, index) => {
return (
<div className="row">
<div className="col-md-6 col-md-offset-3 blog-card">
<BlogCard {...blog} key={blog.blogIdHash} user={props.user} />
<Comments {...blog} key={index} blogId={blog.blogIdHash} csrf={props.csrf}/>
</div>
</div>
);
})
}
</div>
);
}
}
You spotted the error in the wrong line.
The this keyword is missing in user and csrf props:
<BlogCard {...blog} key={blog.blogIdHash} user={this.props.user} />
<Comments {...blog} key={index} blogId={blog.blogIdHash} csrf={this.props.csrf} />

Resources