Content Component in Native Base React is not rendering - javascript

I desigining react native UI using Native base
library(http://docs.nativebase.io/Components.html#anatomy-headref). I am following their most basic example(the skeleton), but the Content Component is not showing up at all. Given that Most of the subcomponentes are depended on this, I am stuck on this library. I could render Grid which make sthis problem more weird for me. I am using there baseline example give in their documentation
http://docs.nativebase.io/Components.html#anatomy-headref ,only header is rendering.
import {Container,Header, Title, Button, Icon,Text} from 'native-base';
//Include Nativebase required components
import React from 'react';
import { StatusBar, StyleSheet ,View} from 'react-native'; //Most of the
react native components can be found in NativeBase
import { Font } from 'expo'; //to include font from expo.
// load up the child components
import BodyComponent from './body_container';
export default class ContainerApp extends React.Component {
//checking state for if font is loaded or not.
state = {
fontLoaded: false,
};
async componentDidMount() {
await Font.loadAsync({
'Roboto_medium': require('native-base/Fonts/Roboto_medium.ttf'),
});
//Setting the state to true when font is loaded.
this.setState({ fontLoaded: true });
}
render() {
return (
this.state.fontLoaded && (
<BodyComponent />
)
);
}
}
body component
export default class BodyComponent extends React.Component {
constructor(props){
super(props);
}
render(){
return(
<Container>
<Header>
<Left>
<Button transparent>
<Icon name='menu' />
</Button>
</Left>
<Body>
<Title>Header</Title>
</Body>
<Right />
</Header>
<Content>
<Text>
This is Content Section
</Text>
</Content>
</Container>
)
}
}
the ui showing up like (Pixel XL android)
The UI
I created repo https://github.com/abdullah2891/react_native_practice

In my case, the version of native base is changed. So I revert it and convert native-base: ^2.15.2

Related

React Lazyload as soon as page interacted with

I'm building a React site which uses live chat and am using the react-livechat package. I've paired this up with the react-lazyload plugin to try to prevent it from adversely affect page load times.
I'm now trying to work out a way to load the livechat component in as soon as the page is interacted with. Currently it only renders when the page is scrolled to within a set distance of the component which by default is the footer of the page. This does prevent the page load being impacted but requires a user to scroll a certain distance before the component loads. Ideally it would load form any interaction with the page.
import React, { Component } from 'react';
import LiveChat from 'react-livechat';
import LazyLoad from 'react-lazyload';
class App extends Component {
render() {
return (
<div className="App">
...
<LazyLoad once>
<LiveChat license={'xxxxxx'} />
</LazyLoad>
...
</div>
);
};
}
export default App;
I managed to get this behavior with a workaround and loading the component after a certain period of time. I found that 10 seconds worked well to ensure even on mobile everything had entirely rendered.
// App.js
import React, { Component } from 'react';
import LazyLiveChat from './components/utils/lazyLiveChat';
class App extends Component {
constructor() {
super();
this.state = { loadLiveChat: false };
}
componentDidMount() {
setTimeout(() => this.setState({loadLiveChat: true}), 10000);
}
render() {
return (
<div className="App">
...
<LazyLiveChat loadChat={this.state.loadLiveChat} />
...
</div>
);
};
}
export default App;
// lazyLiveChat.js
import React, { Component } from 'react';
import LiveChat from 'react-livechat';
class LazyLiveChat extends Component {
render() {
if (this.props.loadChat) {
return (
<LiveChat license={xxxxxx} />
);
}
return null;
}
}
export default LazyLiveChat;

Render a new Component without using router

I've created an application to React, and when it starts, the App component is rendered. I would like that when the user clicks on a button or link, the button or link has to be in the App component when clicking on that link, another component will be rendered but not inside the App component but only the new component will be rendered in the same URL. As for this new component, it has to have a similar button so that when the user clicks, only the App component is rendered and this component that the user has clicked on is not rendered, only the App component.
I do not know if I explained myself correctly. Ask me any question if you need some clarification.
My App component is the following:
import React, { Component } from 'react';
import Touch from './Touch';
import '../App.css';
class App extends Component{
render() {
return(
<div>
<div className="wrapper" >
<button >NewComponent</button><NewComponent />???
<h1>Google Cloud Speech with Socket.io</h1>
<p id="ResultText"><span className="greyText">No Speech to Text yet</span></p>
</div>
<div className="buttonWrapper" >
<button className="btn" id="startRecButton" type="button"> Start recording</button>
<button className="btn" id="stopRecButton" type="button"> Stop recording</button>
</div>
</div>
);
}
}
export default App
My index.js is the following:
import React from 'react';
import ReactDOM from 'react-dom';
import './App.css';
import App from './components/App.js';
import registerServiceWorker from './registerServiceWorker';
ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();
If you really don't want to use react-router you will need to store a value in the component's state and change the rendering method to reflect which button was pressed. If you want each of those component to include the button you need to switch, do the following :
class App extends Component {
constructor(props){
super(props);
this.state = {renderA: false,};
}
handleClick = (event) => {
this.setState((prevState) => ({renderA: !prevState.renderA}));
};
render = () => {
return(
<div>
{this.state.renderA ?
<ComponentA handleClick={this.handleCLick}/>:
<ComponentB handleClick={this.handleCLick}/>
}
</div>
);
};
} export default App;
// ComponentA
class ComponentA extends Component {
render = () => {
return(
<div>
// what you want inside your first page here
<button onClick={this.props.handleClick}
</div>
);
}
} export default ComponentA;
// ComponentB
class ComponentB extends Component {
render = () => {
return(
<div>
// what you want inside your second page here
<button onClick={this.props.handleClick}
</div>
);
}
} export default ComponentB;
But using react-router might also suits your case, and if you are going to write a large app, you should use it instead of rendering differents children components within the same one, based on users inputs.
If the URL stay the same, I don't think React-Router might help you.
If you want that App Component is not loaded, I think you should create two more Component, a Wrapper one, and the new component you want to display (from now on newComponent). What I suggest is:
Creating a property isButtonClicked inside the state of the Wrapper Component;
Creating a function handleButtonClick() inside the Wrapper Component:
handleButtonClick() => {
let isButtonClicked = !this.state.isButtonClicked;
this.setState({ isButtonClicked });
}
In the render() method of the Wrapper component, you write something like this:
render() {
if (this.state.isButtonClicked)
return <App />
else
return <NewComponent />
}
Then, in both App and NewComponent, if you click on the button, you call the this.props.handleButtonClick(), which will lead to a change of the state of Wrapper Component, therefore to a change of what is shown on the screen.

React Context and separate classes

I've given up hope on getting mt head around Redux (I'm new to React), and see the Alpha version of React offers a new Context.
So I am attempting to learn it, and my goal is, I have a Navbar, which I want to respond to a state within my context, {isAuthorised: false}.
I'm following this guys video:
But he has all is code in a single file. I'm trying to do it 'right'.
What I did was created a folder called 'context' and within that, created a jsx called provider.jsx.
import React, {Component} from 'react';
export default class MyProvider extends Component {
constructor(props) {
super(props);
this.state = {
isAuthenticated: false
}
}
render() {
const MyContext = React.createContext();
return(
<MyContext.Provider value="Test Text">
{this.props.children}
</MyContext.Provider>
)
}
}
https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/context/provider.jsx
In there, I created the context within the render (This might be wrong... maybe that's meant to happen in my App jsx?).
I create a state in there, defaulting isAuthenticated to false. (I'll add code later to set that to what it should be).
This compiles... and runs.
In my App component, I use my provider like this:
import MyProvider from './context/provider.jsx';
export default class App extends Component {
render() {
return (
<MyProvider>
<div>
<Router>
<div>
<Navbar />
<Route exact path='/' component={Home} />
<Route path='/about' component={About} />
https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/app.jsx
So I am wrapping all my code with MyProvider.
In my Navbar component, I import my provider:
import MyProvider from '../../context/provider.jsx';
I then try and output somethign from my provider within my render:
return (
<div>
<MyProvider.Consumer>
{(context)=> (
<p>Here I am {context}</p>
)}
</MyProvider.Consumer>
<nav className="navbar navbar-expand">
https://github.com/CraigInBrisbane/ReactLearning/blob/master/src/components/navbar/navbar.jsx
But this goes very badly for me.
Warning: React.createElement: type is invalid -- expected a string
(for built-in components) or a class/function (for composite
components) but got: undefined. You likely forgot to export your
component from the file it's defined in, or you might have mixed up
default and named imports.
Check the render method of Navbar.
in Navbar (created by App)
in div (created by App)
And
Uncaught Error: Element type is invalid: expected a string (for
built-in components) or a class/function (for composite components)
but got: undefined. You likely forgot to export your component from
the file it's defined in, or you might have mixed up default and named
imports.
How can I get this to work? Where should my .createContext reside?
Code (With error) is here.
So the problem is that you export MyProvider and try to access static component on it - which is undefined:
console.log(MyProvider.Consumer); // undefined
the Consumer is existing as a static property only in MyContext component.
What you need to change:
provider.jsx
import React, {Component} from 'react';
export const MyContext = React.createContext();
export default class MyProvider extends Component {
constructor(props) {
super(props);
this.state = {
isAuthenticated: false
}
}
render() {
return(
<MyContext.Provider value={this.state.isAuthenticated}>
{this.props.children}
</MyContext.Provider>
)
}
}
then in navbar.jsx
import MyProvider, { MyContext } from '../../context/provider.jsx';
<MyProvider>
<MyContext.Consumer>
{(context)=> (
<p>Here I am {context}</p>
)}
</MyContext.Consumer>
</MyProvider>
take a look at this tutorial.
EDIT:
To have the Consumer exist in MyProvider you would have to assign static variable on it that points to MyContext Consumer
MyProvider.Consumer = MyContext.Consumer;
Then I think you could use it like:
<MyProvider>
<MyProvider.Consumer>
{(context)=> (
<p>Here I am {context}</p>
)}
</MyProvider.Consumer>
</MyProvider>
However I'm not sure if it is a good idea.
Was getting the same error...
Turns out I was using an older version of react-dom. Updating it to ^16.3.0 fixed it for me!
Thanks to this video I was able to get it working. Here's my solution...
AuthCtrProvider.js
import React, { Component } from 'react';
// create context blank, it gets filled by provider
export const MyContext = React.createContext();
// the state object is initially in the AuthCtrProvider and gets passed into the context
// via the value argument to the provider
export default class AuthCtrProvider extends Component {
state = {
isAuthenticated: false,
counter: 100,
doubl: () => { this.setState({ counter: this.state.counter * 2 } ) }
}
render() {
return (
// pass in this.state (which carries the data and the doubl func and also
// pass in three additional functions
<MyContext.Provider value={{
state: this.state,
toggle: () => { this.setState({ isAuthenticated: !this.isAuthenticated })},
incr: () => { this.setState({ counter: this.state.counter + 1 })},
decr: () => { this.setState({ counter: this.state.counter - 1 })}
}
}>
// include the children that will be wrapped by this provider (in App.js)
{this.props.children}
</MyContext.Provider>
)
}
}
We export the MyContext and the default AuthCtrProvider. This is probably bad form here because I'm mixing a counter with an unrelated isAuthenticated. I'm just doing this to demo the functionality.
Also note - there's a function doubl in the state and there's functions in the provider that are separate from the state. Again, this is only used to make a point further down.
App.js
import React, { Component } from 'react';
import AuthCtrProvider, { MyContext } from './AuthCtrProvider';
class App extends Component {
render() {
return (
<div className="App">
<Navigation />
<AuthCtrProvider>
<MyContext.Consumer>
{(context) => (
<p>Counter from the context = {context.state.counter}</p>
)}
</MyContext.Consumer>
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h1 className="App-title">Welcome to React</h1>
</header>
<Main />
</AuthCtrProvider>
</div>
);
}
}
This shows the counter from the context.state so we can see it at the top level. In the project I have other imports for navigation and routing. One of my pages that loads in is ProjectDetails.jsx...
ProjectDetails.jsx
import React from 'react';
// in this file I only need to import the context
import { MyContext } from '../AuthCtrProvider';
// other imports for presentation components, OData, and such
render() {
return (
<div style={{ display: "flex", flex: "1 1 0", alignItems: "flex-start", overflowY: "auto" }}>
// we get access to the context using 'context' var but it can be whatever name you want
<MyContext.Consumer>
{context => (
<React.Fragment>
// note accessing the 'incr' function which is outside the state so it's just context.incr
<button onClick={context.incr}>incr {context.state.counter}</button>
// note access the 'doubl' function inside the state, hence context.state.doubl
<button onClick={context.state.doubl}>dubl {context.state.counter}</button>
</React.Fragment>
)}
</MyContext.Consumer>
// other presentation going here
</div>
);
}
That's it. Context and provider in a separate file, data and functions accessible from other files.
HTH, Mike

Add loader on button click in react/redux application

I'm trying to add a Loader as Higher-Order-Component on button click in react/redux application.
Already have working Loader component and styling, just need to set logic when button is clicked show loader and hide existing button.
Button component:
import React from 'react'
import '../../../styles/components/_statement-print.scss';
import Loader from './Loader';
const StatementPrint = (props) => {
return (
<div>
<button
className="print-statement-button"
onClick={props.handleStatementPrint}>PRINT
</button>
</div>
);
};
export default Loader(StatementPrint);
Loader:
import React, { Component} from 'react';
import '../../../styles/components/_loader.scss';
const Loader = (WrappedComponent) => {
return class Loader extends Component {
render() {
return this.props.handleStatementPrint // Where must be logic when to show loader or existing button component
? <button className="loader-button">
<div className="loader">
<span className="loader-text">LOADING...</span>
</div>
</button>
: <WrappedComponent {...this.props} />
}
}
}
export default Loader;
In Loader component i added comment where need to write logic when to set loader or button.
I followed this example: ReactCasts - Higher Order Components
I searched a lot of examples but most of them shows how to set loader then is data is fetching, but in my case i just need to show then onClick method is triggered.
So how to set logic when onClick method is fired? Is this is a good aproach? Also it will be better to try acomplish this doing with redux state, but don't know how to do this.
Any help will be appreciated.
You will have to make small modifications to achieve what you want.
The wrapper component Loader can have a isLoading state, on the basis of which you can decide whether to show the loader span or the wrapped component.
This state isLoading can be updated by the wrapped component by passing showLoader function as a prop.
Button component
import React from 'react'
import '../../../styles/components/_statement-print.scss';
import Loader from './Loader';
const StatementPrint = ({handleStatementPrint, showLoader}) => {
return (
<div>
<button
className="print-statement-button"
onClick={() => {
showLoader();
handleStatementPrint();
}}>
PRINT
</button>
</div>
);
};
export default Loader(StatementPrint);
Loader
import React, { Component} from 'react';
import '../../../styles/components/_loader.scss';
const Loader = (WrappedComponent) => {
return class Loader extends Component {
constructor(props) {
super(props);
this.state = {
isLoading: false
}
this.showLoader = this.showLoader.bind(this);
}
showLoader() {
this.setState({isLoading: true});
}
render() {
return this.state.isLoading
? <button className="loader-button">
<div className="loader">
<span className="loader-text">LOADING...</span>
</div>
</button>
: <WrappedComponent
{...this.props}
showLoader={this.showLoader}
/>
}
}
}
export default Loader;
EDIT
Since handleStatementPrint was required to be called, I have updated the click handler to include that function.
Also using de-structuring to avoid typing props repeatedly. See here for more info.
Just some external state is needed.
If you can't have external state (eg isLoading) than you could pass a function into a loader hoc which will derive isLoading from current props
Example: https://codesandbox.io/s/8n08qoo3j2

used wrapper but modal not opening

import React, { PropTypes } from 'react';
import Dialog from 'material-ui/Dialog';
export default class simpleModal extends React.Component {
constructor(props){
super(props)
}
handlePrimaryButton = () => {
this.props.router.push('/some/path');
}
render(){
return(
<Dialog
actions={<RaisedButton
label="OK"
primary={true}
onTouchTap={this.handlePrimaryButton}
/>}
modal={false}
open={this.props.open}
>
{this.props.msg}
</Dialog>
)
}
}
I created a wrapper using material-ui Dialog component but I can't open it. In another component I have this in my render method:
<simpleModal open={this.state.openSimpleModal} />
I then change the state of openSimpleModal using this.setState({openSimpleModal: true})
I don't see the modal being open. Is there anything missing in my above code? I manage to use Dialog component of material-ui directly but not with a wrapper.
Note: No error in chrome console at all.
Old thread but I had the same issue while using a wrapper. Had to use a callback to the parent, not pretty.
The Dialog component in material-ui-next doesn't have this issue any more.

Categories

Resources