I have a ready pagination component: https://www.npmjs.com/package/react-js-pagination
import React, { Component } from "react";
import ReactDOM from "react-dom";
import Pagination from "react-js-pagination";
require("bootstrap/less/bootstrap.less");
class App extends Component {
constructor(props) {
super(props);
this.state = {
activePage: 1,
todos: []
};
}
handlePageChange(pageNumber) {
console.log(`active page is ${pageNumber}`);
this.setState({activePage: pageNumber});
}
render() {
return (
<div>
<Pagination
activePage={this.state.activePage}
totalItemsCount={this.state.todos.length}
pageRangeDisplayed={2}
onChange={this.handlePageChange}
/>
</div>
);
}
}
How to transform pagination from react-js-pagination toreact-bootstrap pagination https://react-bootstrap.github.io/components/pagination/ ?
react-bootstrap pagination is just a UI component that renders the pagination items and can't handle the stuff react-js-pagination is handling. It is mentioned in react-js-pagination docs that you can import your own CSS style and use the classes for the pagination items. So just importing bootstrap style is enough and then you can do this:
import "bootstrap/dist/css/bootstrap.min.css";
<ReactPagination
itemClass="page-item"
linkClass="page-link"
hideNavigation
activePage={2}
itemsCountPerPage={10}
totalItemsCount={450}
pageRangeDisplayed={5}
/>
Check this Codesandbox: https://codesandbox.io/s/polished-darkness-pm7v8?fontsize=14
I use the react-bhx-pagination because you can get the json, auto load when you get to the end of the page and it's very easy to use and change.
Example: Online demo
Component:
react-bhx-pagination
Related
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;
Material UI version: v0.20.0
I am trying to assign leftAvatar value via CustomAvatar component but it is not aligning as you can see in attached screenshot. Please help.
CustomAvatar: This component is working on some condition bases like if image is available the its
MemberList/index.js
import React, {Component} from 'react';
import {withRouter} from 'react-router-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {List, ListItem} from 'material-ui/List';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import CustomAvatar from 'routes/CustomAvatar';
class MemberList extends Component {
render(){<MuiThemeProvider>
<List>
<ListItem
leftAvatar={<CustomAvatar avatarPic={false}/>}
primaryText={"Mike Tailor"}
secondaryText={"This is first text"}
secondaryTextLines={1}
rightIconButton={<IconMenu iconButtonElement={iconButtonElement}>
<MenuItem>Add friend</MenuItem>
<MenuItem>Chat</MenuItem>
</IconMenu>}/>
<ListItem
leftAvatar={<CustomAvatar avatarPic={true}/>}
primaryText={"Kory Becker"}
secondaryText={"This is second text"}
secondaryTextLines={1}
rightIconButton={<IconMenu iconButtonElement={iconButtonElement}>
<MenuItem>Add friend</MenuItem>
<MenuItem>Chat</MenuItem>
</IconMenu>}/>
</List>
</MuiThemeProvider>}
}
export default withRouter(MemberList);
CustomAvatar/index.js
import React, {Component} from 'react';
import {withRouter} from 'react-router-dom';
import Avatar from 'material-ui/Avatar';
class CustomAvatar extends Component {
render(){
if(this.props.avatarPic){
return(<Avatar size={40} src={"http://www.example.com/myimage.png"} />)
}else{
return(<Avatar size={40}>A</Avatar>)
}
}
}
export default withRouter(CustomAvatar);
The cause of your problem
Your problem is caused because the material-ui v0 library expects the leftAvatar prop to be an Avatar component, and so relies on internal values of Avatar behind the scenes. Since your CustomAvatar is not directly an Avatar, material-ui does not find these internals and so the styling does not work.
Specifically, if you take a look at the source of ListItem, you'll notice a pushElement function that takes child components like leftAvatar and assigns styling by setting the style prop:
pushElement(children, element, baseStyles, additionalProps) {
if (element) {
const styles = Object.assign({}, baseStyles, element.props.style);
children.push(
React.cloneElement(element, {
key: children.length,
style: styles,
...additionalProps,
})
);
}
}
Your CustomAvatar makes no use of this style prop, so you never receive the necessary CSS styling. That's the cause of your layout issues.
You have a couple of options to fix this depending on whether you are willing to upgrade to v1 or not.
Code that fixes it
class CustomAvatar extends Component {
render() {
const { showPicture, ...other } = this.props;
if (showPicture) {
return (<Avatar size={40} {...other} src={"http://www.example.com/myimage.png"} />);
} else {
return (<Avatar size={40} {...other}>A</Avatar>);
}
}
}
As discussed above, the pushElement function sets the style prop. Right now, you're not using it, so your Avatars get no styling. The {...other} spreads this prop down into your Avatars so that they get the right styling and your layout works.
But, you should upgrade to v1
v1 should have a stable release in the early quarters of 2018, and it fixes a lot of these kinds of problems. Instead of spending time working through these kinds of issues and working with v0, you should upgrade and learn the new (and, imho, improved) way.
I also have faced same problem you could fix this by wrap your custom compoent into PAPER component of material-ui. Please see code below:
import React, {Component} from 'react';
import {withRouter} from 'react-router-dom';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import {List, ListItem} from 'material-ui/List';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import CustomAvatar from 'routes/CustomAvatar';
import Paper from 'material-ui/Paper';
class MemberList extends Component {
render(){<MuiThemeProvider>
<List>
<ListItem
leftAvatar={<Paper zDepth={2} circle={true}><CustomAvatar avatarPic={false}/></Paper>}
primaryText={"Mike Tailor"}
secondaryText={"This is first text"}
secondaryTextLines={1}
rightIconButton={<IconMenu iconButtonElement={iconButtonElement}>
<MenuItem>Add friend</MenuItem>
<MenuItem>Chat</MenuItem>
</IconMenu>}/>
<ListItem
leftAvatar={<Paper zDepth={2} circle={true}><CustomAvatar avatarPic={true}/></Paper>}
primaryText={"Kory Becker"}
secondaryText={"This is second text"}
secondaryTextLines={1}
rightIconButton={<IconMenu iconButtonElement={iconButtonElement}>
<MenuItem>Add friend</MenuItem>
<MenuItem>Chat</MenuItem>
</IconMenu>}/>
</List>
</MuiThemeProvider>}
}
export default withRouter(MemberList);
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
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
I have the below component. It is not rendering the product module in the dom and also not showing any error in the console.
And if I use ReactDOM.render(<ProductModule/>,document.getElementById('product-container')); it is working.
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class ProductModuleWrapper extends Component {
constructor(props) {
}
render() {
return (
<div className="product-container">
{this.renderProductModules()}
</div>
);
}
renderProductModules() {
require.ensure([],(require) => {
var ProductModule = require('../ProductModule').default;
return ProductModule;
},'productmodule');
}
}
edit :
I think this is something to do with the async nature of the require ensure call, Please help
React will only re-render if component's state or props have been updated. In your example, neither is so it won't render the component as it's fetched asynchronously.
I recommend that you use this.state as described in this blog post: http://blog.netgusto.com/asynchronous-reactjs-component-loading-with-webpack/