Export a dynamic array from a React component to another component - reactjs

I built a react component that imports a Json file into an array to map the result. I need that array in another component. I don't know if I must built this component inside the new component or if there's a method to export the needed array (data). The array source is updated every 4 seconds.
Thanks for your help.
My first component is:
import React from 'react';
import ReactDOM from 'react-dom';
import axios from 'axios';
class Ramas extends React.Component {
constructor(props) {
super(props);
this.state = {
data: []
};
}
componentDidMount() {
const fetchData = () => {
axios
.get('http://localhost:8888/dp_8/fuente/procesos_arbol.json')
.then(({ data })=> {
this.setState({
data: data
});
console.log(data);
})
.catch(()=> {console.log('no recibido');});
};
fetchData();
this.update = setInterval(fetchData, 4000);
} // final componentDidMount
render() {
const initialData = this.state.data.map((el) => {
return (
<p>id={ el.id } | name - { el.name } | padre - {el.parent}</p>
);
});
return (<div className="datos_iniciales">
{ initialData }
</div>);
}
}
ReactDOM.render(
<Ramas />,
document.getElementById('container')
);

make one top level component that can contain the two components.
in the Ramas component ->
const updatedData = setInterval(fetchData, 4000);
this.props.datasource(updatedData);
write a new top level component ->
class TopComponent Extends React.Component{
state = {data: ''}
handleDataUpdate = (updatedData) => {
this.setState({data: updatedData});
}
render = () => {
<Ramas datasource={this.handleDataUpdate}>
<SecondComponent updatedData={this.state.data}>
</Ramas>
}
}
now from SecondComponent updatedData prop you can get the fresh data
By the way it is in ES7 syntax I wrote

If you have parent component, you should pass function from it to this component as a prop.
That function will than set state and data will flow one way as it's imagined with ReactJS.
For example instead of this.setState, you could call
this.props.jsonToArray
and in jsonToArray you should call setState which will pass data to that seccond component.

Related

The data that comes from an API end point is undefined in the child component in React

Good day to all!
I have this situation: I use Apollo client to get data from a GraphQL API endpoint in the parent class component in React. I pass this data to the child class component. The first time everything works fine but after a page refresh the data in the child component becomes undefined and the app crashes.
Here is the representation of the situation:
The ParentComponent
import React, { Component } from 'react'
import { gql } from "apollo-boost";
import {graphql} from 'react-apollo';
import ChildComponent from './ChildComponent'
const getProducts = gql`
{
category {
products {
id
name
gallery
}
}
}
`
class ParentComponent extends Component {
constructor(props) {
super(props)
this.state = {
products: []
}
}
componentDidMount() {
setTimeout(() => {
this.setState({
products: [...this.props.data.category.products]
})
}, 1000)
}
render () {
let products = this.state.products;
return (
<div><ChildComponent theProducts = {products}/></div>
)
}
}
export default graphql(getProducts)(ParentComponent);
The ChildComponent
import React, { Component } from 'react'
class ChildComponent extends Component {
constructor(props) {
super(props)
this.state = {
products: this.props.theProducts
}
}
render () {
let item = this.state.products.find(each => each.id === id);
return (
<div>
<ul>
<li>{item.name}</li>
<li><img src= {item.gallery[0]} alt="product"></img></li>
</ul>
</div>
)
}
}
export default ChildComponent;
So, when the app starts everything seems to work fine. But if I refresh the page it throws an error and says that name is undefined, gallery is undefined. It is clear that the data is not coming through to the ChildComponent. Is there a way to make sure that the data comes in at any time?
Thank you in advance.
You use theProducts in the ChildComponent but you pass theProduct from ParentComponent . And state product also has the same error. Just update to theProducts and product

How to use map on multi objects array in React

This is child component as i can you Props here
Child Component:
import React from "react";
const PeopleList = props => {
console.log("child Props :", props.data);
const list = props.data.map(item => item.name);
return <React.Fragment>{"list"}</React.Fragment>;
};
export default PeopleList;
Main Component:
import React, { Component } from "react";
import { connect } from "react-redux";
import { fetchPeople } from "../actions/peopleaction";
import PeopleName from "../containers/peopleName";
class Main extends Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
this.props.dispatch(fetchPeople());
}
render() {
const { Error, peoples } = this.props;
console.log("data", peoples);
return (
<div className="main">
{"helo"}
<PeopleName data={peoples.results} />
</div>
);
}
}
const mapStateToProps = state => {
return {
peoples: state.peoples.peoples,
error: state.peoples.error
};
};
export default connect(mapStateToProps)(Main);
If i iterate the props multi objects array i can face Map is not define issue;
I need to iterate the props.data multi objects array in child component and i get object from Redux store. once component loaded the redux store.
can you please some one help me on this.
you can find whole code below mentioned
Try this It works in your codesandbox.
{peoples.results && <PeopleName data={peoples.results} />}

Attaching / Detaching Listeners in React

I have a component which, depending on its prop (listId) listens to a different document in a Firestore database.
However, when I update the component to use a new listId, it still uses the previous listener.
What's the correct way to detach the old listener and start a new one when the component receives new props?
Some code:
import React from 'react';
import PropTypes from 'prop-types';
import { db } from '../api/firebase';
class TodoList extends React.Component {
state = {
todos: [],
};
componentWillMount() {
const { listId } = this.props;
db.collection(`lists/${listId}/todos`).onSnapshot((doc) => {
const todos = [];
doc.forEach((t) => {
todos.push(t.data());
});
this.setState({ todos });
});
};
render() {
const { todos } = this.state;
return (
{todos.map(t => <li>{t.title}</li>)}
);
}
}
TodoList.propTypes = {
listId: PropTypes.object.isRequired,
};
export default TodoList;
I've tried using componentWillUnmount() but the component never actually unmounts, it just receives new props from the parent.
I suspect that I need something like getDerivedStateFromProps(), but I'm not sure how to handle attaching / detaching the listener correctly.
Passing a key prop to the TodoList lets the component behave as it should.

How to display data in store in redux?

I just started with reacts/redux and trying to get my head around store/state. I built a component which successfully receives data and then passes this into the reducer. This is my component:
'use strict';
var React = require('react');
var PropTypes = React.PropTypes;
import axios from 'axios';
import store from '../../store';
import {getDataSuccess, getDataFail} from '../../actions/userData-actions'
import {connect} from 'react-redux';
class ServiceDetails extends React.Component {
constructor(props) {
super(props);
this.state = {
tabs: null,
tabContent: null
}
}
componentDidMount() {
axios.get('http://localhost:3001/0')
.then(response => {
console.log('getservicedetails=response.data', response.data);
store.dispatch(getDataSuccess(response.data));
return response;
})
.catch(function (error) {
console.log(error);
store.dispatch(getDataFail(error));
});
}
render() {
return (
<section className="ServiceDetails">
<h1>id:{props.userData.users[0].id}</h1>
service details new
</section>
)
}
}
const mapStateToProps = function (store) {
console.log('Servicedetails mapStatetoprops =',store );
return {
data: store.datas,
userData: store.apiData
};
};
export default connect(mapStateToProps)(ServiceDetails);
The mapstatetoProps function receives the data but how can I render this data? How can I display the data from the store?
I could not see reducer in your code. Also your function this
const mapStateToProps = function (store) {
return {
data: store.data,
userData: store.apiData
};
};
will map new state to props, & that will re-render your component. As a result
your component will be updated with new/updated data.
Also please verify and fix if possible these stuff:
You should use this.props.userData not props.userData in your render function.
Using of Provider, so that store is used across all components.
One more thing, typo [ " datas " ] in your mapStateToProps function.
single unit of data is called datum & more than one datum is called data not datas.
I found it , I am checking whether the array length is larger than 0 before rendering it.

Setting component state, but this.props.state is undefined in render() method

I'm making a get request within my component's componentDidMount() method. I'm able to successfully make the request and set my component's state. However, when I try to get access to state within my render() method, it comes back as undefined. I'm guessing it has something to do with the asynchronous nature of javascript, but can't seem to figure out how to properly set the state, wait to make sure that state has been set, then pass it down to my render() method so I can access it there. Thanks.
Game.js (component file)
import React, { Component } from 'react';
import { Link } from 'react-router';
import axios from 'axios';
export default class Game extends Component {
constructor(props) {
super(props)
this.state = {
data: []
};
}
getReviews() {
const _this = this;
axios.get('/api/reviews')
.then(function(response) {
_this.setState({
data: response.data
});
console.log(_this.state.data); // shows that this is an array of objects.
})
.catch(function(response) {
console.log(response);
});
}
componentDidMount() {
this.getReviews();
}
render() {
const allReviews = this.props.data.map((review) => {
return (
<li>{review.username}</li>
);
})
console.log(this.props.data); // comes in as undefined here.
return (
<div>
{allReviews}
</div>
);
}
}

Resources