How we can share state object to another react file - javascript

in the first react file i called an api to get some data and save it in this.state.Data
import React, { Component } from "react";
import axios from "axios";
import Layout from "./Layout";
class Db extends Component {
constructor() {
super();
this.state = {
Data: [],
};
}
componentDidMount() {
axios.get(`https://breakingbadapi.com/api/characters`).then((res) => {
const data = res.data;
this.setState({ Data: data });
});
}
render() {
return <h1>DB working</h1>;
}
}
export default Db;
in the another react file i need to get this.props.Data from Db.js file but i dont know how to get it
import React, { Component } from "react";
import Db from "./Db";
class Filler extends Component {
constructor() {
super();
}
render() {
return <div></div>;
}
}
export default Filler;

for small projects you can use React ContextApi to save states in global level and use it inside components you want.
for big projects you can use state management libraries like Redux. it's too much for small projects.

Related

How To Run React Native lifecycle on another Component

I tried to make a network availability component for my app.
My lifecycle component in the network.js
import { Component } from 'react';
import { NetInfo } from 'react-native';
export default class Network extends Component {
constructor(props) {
super(props);
this.state = { connected: null }
}
componentWillMount() {
NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectionChange);
NetInfo.isConnected.fetch().done((isConnected) => this.setState({ connected: isConnected }))
}
componentWillUnmount() {
NetInfo.isConnected.removeEventListener('connectionChange', this.handleConnectionChange);
}
handleConnectionChange = (isConnected) => { this.setState({ connected: isConnected }) }
situation() {
if(this.state.connected)
return true
else
return false
}
}
And my main page :
import React, { Component } from 'react';
import { View, I18nManager, StatusBar, StyleSheet, Text } from 'react-native';
import { Spinner } from 'native-base';
import Network from './Network'
export default class Intro extends Component {
constructor() {
super();
I18nManager.allowRTL(true);
I18nManager.forceRTL(true);
}
render() {
var network = new Network;
alert(network.situation())
if (network==true) {
alert('online')
else
alert('offline')
}
}
But after execution, componentWillMount and componentWillUnmount are not working.
There is really no need to make React component for checking Network connection utility. You can just create a simple Network class like this and initialize/deinitialize it from your app component's lifecycles.
import { NetInfo } from 'react-native';
const NET_INFO = {};
let instance;
export default class Network {
static getInstance() {
return instance || new Network();
}
static initialize() {
NetInfo.isConnected.addEventListener('connectionChange', Network.getInstance().handleConnectionChange);
}
static deinitialize() {
NetInfo.isConnected.removeEventListener('connectionChange', Network.getInstance().handleConnectionChange);
}
handleConnectionChange = (isConnected) => {
NET_INFO.isConnected = isConnected;
}
static isInternetConnected() {
return NET_INFO.isConnected;
}
}
App component:
import React, { Component } from 'react';
import Network from './Network'
export default class Intro extends Component {
componentWillMount() {
Network.initialize();
}
componentWillUnmount() {
Network.deinitialize();
}
render() {
const connected = Network.isInternetConnected()
if (connected ==true)
alert('online')
else
alert('offline')
}
}
Because you are not using Network class as component but as a normal class.
If you want to run life-cycle methods then you need use it as Component.
like this in render method,
<Network />
and if you want to execute anything in parent for network change then use prop functions.
like this in render method,
<Network
connectivityChange={()=>{
//do your stuffs here
}}
/>
you need to call this.props.connectivityChange() in Network component when you want do something in parent.

How to export React class getter with injectIntl?

This is my class:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { injectIntl, intlShape } from 'react-intl';
class MyClass extends Component {
constructor(props) {
super(props);
}
get pageTitle() {
const { intl } = this.props;
return intl.formatMessage({id: 'messages_my_class_page_title'});
}
render() {
return (
<div>
Dummy content
</div>
);
}
}
MyClass.propTypes = {
intl: intlShape.isRequired
}
export default injectIntl(MyClass);
My page title appears when I put in a random text and don't use react-intl injectIntl function.
I have 'react-intl' working fine for all other cases. Even for static properties using 'hoist-non-react-statics' library.
I am stumbled upon this one.
Edit 1:
I can fix it using
<FormattedMessage id="messages_my_class_page_title"/>
But I want to know how to use injectIntl way.

React infinite loop caused by component

I'm currently in the process of learning react and have come across a problem has had me stuck for most of the day. I have two simple components. Once called IncidentsBoard which holds other components called Incidents.
The idea is that (using dummy data) the IncidentBoard will show incidents of car crashes on it. My code:
IncidentBoard:
import React from 'react';
import Incident from './Incidents';
import testData from './testdata';
class IncidentBoard extends React.Component {
constructor(props) {
super(props);
this.state = {
data: testData.features,
filtered: []
}
}
componentWillMount() {
var filtered = this.state.data.filter( (incident, i) => {
return incident.properties.event_type === 'Crash';
})
console.log(filtered);
this.setState({filtered})
}
render() {
return <div>
{this.state.filtered.map((incident, i) => {
return <Incident id={i} description="swagg" />
})}
</div>
}
}
export default IncidentBoard;
Incident (which is currently mostly empty):
import React from 'react';
class Incident extends React.Component {
render() {
return <div><h1>test</h1></div>
}
}
export default Incident;
When running this, it causes an infinite loop where componentWillMount() is run without end. I have also noticed that if I replace the Incident component in the render function in IncidentBoard that the error no longer happens.
EDIT: More code
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import IncidentBoard from './Incidents';
ReactDOM.render(
<IncidentBoard />, document.getElementById('react-container')
)
testData is a just a big JSON object.

How to call component reference from another component in react?

I use react-notification-system library, and found my code more or less like this.
import React from 'react';
import Notification from 'react-notification-system';
class Notif extends React.Component {
constructor(props) {
super(props);
this.notificationSystem = null;
}
componentDidMount() {
// how to export this?
this.notificationSystem = this.refs.notificationSystem;
}
render() {
return <Notification ref="notificationSystem" />;
}
}
export default Notif;
How can I export that notificationSystem so I can use it everywhere?
Two ways:
Use global widget.
Just add a global widget as follow.
var _component
export function set(component) {
_component = component
}
export function get() {
return _component
}
And then in your AppComponent register it:
import {set} from './notify'
class App extends React.Component {
componentDidMount() {
set(this.refs.notificationSystem)
}
}
In any other component, call it:
import {get} from './notify'
class AnyComponent extends React.Component {
alert() {
get().doSomething()
}
}
Use react context to store it as a global props for all component.

Trouble using actions in react-redux presentational component

I'm new to redux and having trouble wrapping my head around presentational and container components.
Relevant stack:
react v0.14.8
react-native v0.24.1
redux v3.5.2
react-redux v4.4.5
The issue:
I have a login button component, which when rendered checks the login status and calls the onSuccessfulLogin action which updates the state with the user's Facebook credentials.
However, when trying to separate this into separate presentational/container components, I'm unable to call the onSuccessfulLogin action: Error: onSuccessfulLogin is not defined.
What am I doing wrong here? I'd imagine there's something simple that I'm not understanding with the relationship between the two components and the connect() function.
Presentational Component (Login.js)
import React, { PropTypes } from "react-native";
import FBLogin from "react-native-facebook-login";
import UserActions from "../users/UserActions";
class LoginPage extends React.Component {
render() {
const { userData, onSuccessfulLogin } = this.props;
return (
<FBLogin
permissions={["email","user_friends"]}
onLoginFound= { data => {
onSuccessfulLogin(data.credentials);
}}
/>
)
}
};
export default LoginPage;
Container Component (LoginContainer.js)
import { connect } from 'react-redux';
import LoginPage from "../login/LoginPage";
import UserActions from "../users/UserActions";
const mapDispatchToProps = (dispatch) => {
return {
onSuccessfulLogin: (userData) => {
dispatch(UserActions.userLoggedIn(userData))
}
}
}
const mapStateToProps = (state) => {
return {
userData: state.userData
}
}
const LoginContainer = connect(
mapStateToProps,
mapDispatchToProps
)(LoginPage);
export default LoginContainer;
Also, if I wanted to make the updated state.userData accessible to the LoginPage component, how would I do that? Any help is appreciated!
Solved! When using ES6 classes, you're required to call super(props) in a constructor method in order to access the container's properties in the connected presentational component:
class LoginPage extends React.Component {
constructor(props){
super(props);
}
render(){
// ...
}
}
Your container component is supposed to be a component and it must have a render function with the dumb/presentational components you want to render.
import { connect } from 'react-redux';
import LoginPage from "../login/LoginPage";
import UserActions from "../users/UserActions";
class LoginContainer extends React.Component {
constructor(props){
super(props);
}
render() {
return (
<LoginPage userData={this.props.userData}
onSuccessfulLogin={this.props.onSuccessfulLogin}
/>
)
}
};
const mapDispatchToProps = (dispatch) => {
return {
onSuccessfulLogin: (userData) => {
dispatch(UserActions.userLoggedIn(userData))
}
}
}
const mapStateToProps = (state) => {
return {
userData: state.userData
}
}
export default connect(
mapStateToProps,
mapDispatchToProps
)(LoginPage);

Categories

Resources