Is there a performance difference in React between 1, 2 and 3?
1.
class App extends Component {
renderHeader = () => <h1>Hello</h1>;
render() {
return <div>
{this.renderHeader()}
</div>;
}
}
2.
class App extends Component {
render() {
return <div>
<h1>Hello</h1>
</div>;
}
}
3.
class App extends Component {
render() {
return <div>
<Header />
</div>;
}
}
class Header extends Component {
render() {
return <h1>Hello</h1>;
}
}
Related
I have this route
<Route path="/Info/:id/:name/:type">
<Info />
</Route>;
And this is Info Page
export default class Info extends React.PureComponent {
public state = {
}
componentDidMount () {
}
render () {
return (
<div>
this is info
</div>
)
}
}
How do i get query strings id, name and type to info
Try useParams from react-router-dom.
ie;
import React from "react";
import {
useParams
} from "react-router-dom";
export default class Info extends React.PureComponent {
componentDidMount() {
}
render() {
let { id, name, type } = useParams();
return (
<div>
this is info
</div>
);
}
}
You can use the match object of react-router.
Class Info extends React.PureComponent{
render(){
return(
<h2>{this.props.match.params.id}</h2>
)
}
}
Read more on match object here
If you are using react-router-dom 5.1
Then you can use the useParams.
Read more on useParams here
My Parent component is like - Requestdetails component
import React, { Component } from "react";
import TopBarComponent from '../../common/TopBar/topBar'
export default class RequestDetailsComponent extends Component {
showBreadcrumb: boolean;
breadcrumbs: { title: string; navigate: string; state: boolean; }[];
constructor(props: any) {
super(props)
this.showBreadcrumb = true;
this.breadcrumbs = [
{ title: 'Dashboard', navigate: 'dashboard', state: true },
{ title: 'Requests', navigate: 'requestList', state: true },
{ title: 'Request Details', navigate: '', state: false }]
}
render() {
return (
<div>
<TopBarComponent showBreadcrumb={this.showBreadcrumb} breadcrumbs={this.breadcrumbs}/>
</div>
);
}
}
Child component -- TopBar component
import React, { Component } from "react";
import { Breadcrumb, BreadcrumbItem } from 'carbon-components-react'
export default class TopBarComponent extends Component {
showBreadcrumb:boolean;
constructor(props:any){
super(props);
this.showBreadcrumb = props.showBreadcrumb
}
render() {
let breadcrumbClass = 'dte-breadcrumbs dte-breadcrumbs--with-layout';
if(this.showBreadcrumb){
return (
<div className={breadcrumbClass}>
<div className="dte-page-container">
<div className="container-fluid">
<Breadcrumb >
<BreadcrumbItem>
Breadcrumb 1
</BreadcrumbItem>
</Breadcrumb>
</div>
</div>
</div>
);
}
return null;
}
}
I want to pass 'showBreadcrumb' and 'breadcrumbs' array to topBar component from Requestdetails component. but unable to do it in react-redux.
The above approach i used to follow in react but now i'm trying this react-redux., but failed to pass.
Please advise how i can pass this.
Assuming you have your redux store and provider setup and configured correctly, the way to connect UI components to your redux store, believe it or not, is with react-redux's connect HOC.
import React, { Component } from "react";
import { connect } from 'react-redux'; // import the connect HOC
import { Breadcrumb, BreadcrumbItem } from "carbon-components-react";
class TopBarComponent extends Component {
render() {
let breadcrumbClass = "dte-breadcrumbs dte-breadcrumbs--with-layout";
if (this.props.showBreadcrumb) {
return (
<div className={breadcrumbClass}>
<div className="dte-page-container">
<div className="container-fluid">
<Breadcrumb>
<BreadcrumbItem>
Breadcrumb 1
</BreadcrumbItem>
</Breadcrumb>
</div>
</div>
</div>
);
}
return null;
}
}
// define a function that maps your redux state to props
const mapStateToProps = state => ({
breadcrumbs: state.breadcrumbs, // these should match how your reducers define your state shape
showBreadcrumb: state.showBreadcrumb,
});
// export the connected component
export default connect(mapStateToProps)(TopBarComponent);
I'm trying to create a live search-result component(lazy load one). It works perfectly for the first time but refetch doesn't update the data. I see the request and respoonse in Network tab! so it does get the data, but it doesn't supply it to the component!
any idea why?
import React, { Component } from 'react';
import {
createRefetchContainer,
graphql,
} from 'react-relay';
import ProfileShow from './ProfileShow';
class ProfileList extends Component {
render() {
console.log("rendering....", this.props)
return (
<div className="row">
<input type="text" onClick={this._loadMe.bind(this)} />
{this.props.persons.map((person) => {
return (
<div className="col-md-3">
<ProfileShow person={person} />
</div>
);
})}
</div>
);
}
_loadMe(e) {
const refetchVariables = fragmentVariables => ({
queryStr: e.target.value,
});
this.props.relay.refetch(refetchVariables, null, (...data) => {
console.log(data)
});
}
}
const FragmentContainer = createRefetchContainer(
ProfileList,
{
persons: graphql.experimental`
fragment ProfileList_persons on Person #relay(plural: true) {
fullname
number
email
pic
}
`
},
graphql.experimental`
query ProfileListRefetchQuery($queryStr: String!) {
talentList(query: $queryStr) {
...ProfileList_persons
}
}
`,
);
export default FragmentContainer;
Hello i have this code
import React from 'react'
import Link from 'react-router/lib/Link'
import { connect } from "react-redux"
import { load } from '../../actions/customerActions'
import List from './list';
import MdAdd from 'react-icons/lib/md/add'
#connect(store => {
return {
customers: store.customer.customers
}
})
export default class Customer extends React.Component {
componentDidMount() {
this.props.dispatch(load({location:localStorage.getItem('locationb')}));
}
render() {
const { customers } = this.props;
const tea = customers.customers && customers.customers.map(customer => <List key={customer.profile} customer={customer} />) || [];
return(
<div class="container">
{ customers.customers ?
<div class="columns is-multiline mb-100">
{ tea }
</div>
: 'Não exitem Clientes'}
<Link to="/customer/create" class="button is-info btn-rounded" title="Novo"><MdAdd /></Link>
</div>
)
}
}
But i only have access to customers in render passing this props.
How can i pass customer to a state variable in component did mount or else ?
i mean customers const { customers } = this.props; how i make like this.setState({customers: customers}) Having in the beginning this.state(customers: [])
YOu can use
componentWillReceiveProps(newProps){
console.log(newProps.customers.customers)
this.setState({customers: newProps.customers.customers})
}
it works for me
thanks
Carlos Vieira
I have a reactjs component with redux which passes asynchronously props to child component.
In child component I try to catch the data in componentDidMount but somehow does not work either, however the child component is getting rendered.
This is my parent component
import React from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import * as slidesActions from '../../actions/slidesActions';
import Slider from '../Partials/Slider'
import _ from 'underscore';
class HomePage extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
this.props.actions.getSlides()
}
componentWillMount() {
const {slides} = this.props;
}
render() {
const {slides} = this.props;
return (
<div className="homePage">
<Slider columns={1} slides={slides} />
</div>
);
}
}
function mapStateToProps(state) {
return {
slides: state.slides
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators(slidesActions, dispatch)
};
}
export default connect(mapStateToProps, mapDispatchToProps)(HomePage);
here comes my child component where I try to get passed slides props but is empty
import React from 'react';
import _ from 'underscore';
import Hammer from 'hammerjs';
class Slider extends React.Component {
constructor(props) {
super(props)
this.updatePosition = this.updatePosition.bind(this);
this.next = this.next.bind(this);
this.prev = this.prev.bind(this);
this.state = {
images: [],
slidesLength: null,
currentPosition: 0,
slideTransform: 0,
interval: null
};
}
next() {
const currentPosition = this.updatePosition(this.state.currentPosition - 10);
this.setState({ currentPosition });
}
prev() {
//TODO: work on logic
if( this.state.currentPosition !== 0) {
const currentPosition = this.updatePosition(this.state.currentPosition + 10);
this.setState({currentPosition});
}
}
componentDidMount() {
//here I try set a state variable on slides
let {slides} = this.props
let slidesLength = slides.length
this.setState({slidesLength})
this.hammer = Hammer(this._slider)
this.hammer.on('swipeleft', this.next);
this.hammer.on('swiperight', this.prev);
}
componentWillUnmount() {
this.hammer.off('swipeleft', this.next)
this.hammer.off('swiperight', this.prev)
}
updatePosition(nextPosition) {
const { visibleItems, currentPosition } = this.state;
return nextPosition;
}
render() {
let {slides, columns} = this.props
let {currentPosition} = this.state
let sliderNavigation = null
//TODO: this should go to slides actions
let slider = _.map(slides, function (slide) {
let Background = slide.featured_image_url.full;
if(slide.status === 'publish')
return <div className="slide" id={slide.id} key={slide.id}><div className="Img" style={{ backgroundImage: `url(${Background})` }} data-src={slide.featured_image_url.full}></div></div>
});
if(slides.length > 1 ) {
sliderNavigation = <ul className="slider__navigation">
<li data-slide="prev" className="" onClick={this.prev}>previous</li>
<li data-slide="next" className="" onClick={this.next}>next</li>
</ul>
}
return <div ref={
(el) => this._slider = el
} className="slider-attached"
data-navigation="true"
data-columns={columns}
data-dimensions="auto"
data-slides={slides.length}>
<div className="slides" style={{ transform: `translate(${currentPosition}%, 0px)`, left : 0 }}> {slider} </div>
{sliderNavigation}
</div>
}
}
export default Slider;
and here I have my actions for slider
import * as types from './actionTypes';
import axios from 'axios';
import _ from 'underscore';
//TODO: this should be accessed from DataService
if (process.env.NODE_ENV === 'development') {
var slidesEndPoint = 'http://dev.server/wp-json/wp/v2/slides';
} else {
var slidesEndPoint = 'http://prod.server/wp-json/wp/v2/slides';
}
export function getSlides () {
return dispatch => {
dispatch(setLoadingState()); // Show a loading spinner
axios.get(slidesEndPoint)
.then(function (response) {
dispatch(setSlides(response.data))
dispatch(doneFetchingData(response.data))
})
/*.error((response) => {
dispatch(showError(response.data))
})*/
}
}
function setSlides(data) {
return {
type: types.SLIDES_SUCCESS,
slides: data
}
}
function setLoadingState() {
return {
type: types.SHOW_SPINNER,
loaded: false
}
}
function doneFetchingData(data) {
return {
type: types.HIDE_SPINNER,
loaded: true,
slides: data
}
}
function showError() {
return {
type: types.SHOW_ERROR,
loaded: false,
error: 'error'
}
}
Reason is, componentDidMount will get called only once, just after the initial rendering, since you are fetching the data asynchronously so before you get the data Slider component will get rendered.
So You need to use componentwillreceiveprops lifecycle method.
componentDidMount:
componentDidMount() is invoked immediately after a component is
mounted. Initialization that requires DOM nodes should go here. If you
need to load data from a remote endpoint, this is a good place to
instantiate the network request. Setting state in this method will
trigger a re-rendering.
componentWillReceiveProps:
componentWillReceiveProps() is invoked before a mounted component
receives new props. If you need to update the state in response to
prop changes (for example, to reset it), you may compare this.props
and nextProps and perform state transitions using this.setState() in
this method.
Write it like this:
componentWillReceiveProps(nextProps){
if(nextProps.slides){
let {slides} = nextProps.props
let slidesLength = slides.length;
this.hammer = Hammer(this._slider)
this.hammer.on('swipeleft', this.next);
this.hammer.on('swiperight', this.prev);
this.setState({slidesLength})
}
}
As far as I understand, you are doing an axios call to fetch the data and then set it in the reducer which you are returning later. Also initially reducer data is empty . Now since componentDidMount is called only once, and initially no data may have been there you are not seeing any values. Use a componentWillReceiveProps function
componentWillReceiveProps(nextProps) {
//here I try set a state variable on slides
let {slides} = nextProps
let slidesLength = slides.length
this.setState({slidesLength})
this.hammer = Hammer(this._slider)
this.hammer.on('swipeleft', this.next);
this.hammer.on('swiperight', this.prev);
}