React props of parent are not passed to child component - reactjs

I'm passing props to a child component, from a parent component that receive this same prop from his own parent.
For some reason, when the parent props get updated, this update does not affect the child component.
The component in itself is very basic:
here's the parent :
import React, { Component } from 'react'
import styled from 'styled-components'
import { Icon } from 'antd'
import BaseProductSelector from '../BaseProductSelector'
import BaseProductPreview from '../BaseProductPreview'
import FullDesignSelector from '../FullDesignSelector'
import ColorPicker from '../ColorPicker'
import GeneratorProgress from '../GeneratorProgress'
import GeneratorError from '../GeneratorError'
import BPDetails from './BPDetails'
const GeneratorFlow = styled.div`
/*background-color: #eeeeee;*/
padding: 0 60px;
h3 {
color: #444;
}
.innerGenFlow {
padding: 15px;
border-radius: 5px;
box-shadow: 0 20px 40px -14px rgba(0, 0, 0, 0.35);
}
`
export default class ProductGeneratorFlow extends Component {
constructor(props) {
super()
let colors
if (props.product) {
colors = props.product.variations.filter(p => p.type === 'color')
} else {
colors = []
// colors.push(props.baseProduct.variations.filter(p => p.type === 'color')[0])
}
this.state = {
pickedColors: colors,
done: false,
error: false,
}
this.setStep = this.setStep.bind(this)
this.setKey = this.setKey.bind(this)
this.showBP = this.showBP.bind(this)
this.hideBP = this.hideBP.bind(this)
this.onChange = this.onChange.bind(this)
this.toggleColor = this.toggleColor.bind(this)
this.toggleAll = this.toggleAll.bind(this)
this.productCreated = this.productCreated.bind(this)
this.productPending = this.productPending.bind(this)
this.setFirstColor = this.setFirstColor.bind(this)
this.displayError = this.displayError.bind(this)
}
setStep(step) {
this.setState({ step })
}
showBP() {
this.setState({ BPDisplayed: true })
}
hideBP() {
this.setState({ BPDisplayed: false })
}
getBaseProd() {
const bpid = this.props.product.supplierBaseProductId
const result = this.props.base_products.filter(obj => obj._id === bpid)
return result[0]
}
setKey(activeKey) {
this.setState({
activeKey,
})
}
onChange(activeKey) {
this.setState({
activeKey,
})
}
productPending() {
this.setState({
done: false,
error: false,
})
this.props.showBP()
}
productCreated() {
this.props.displaySuccess()
this.setState({ done: true })
}
displayError() {
this.setState({ error: true })
}
toggleColor(color) {
let pickedColors = this.state.pickedColors
if (this.state.pickedColors.includes(color)) {
// console.log(pickedColors.filter(i => i != color).length)
pickedColors = pickedColors.filter(i => i != color)
} else {
pickedColors.push(color)
}
this.setState({
pickedColors,
})
}
test(id) {
this.setState({picked: true})
this.props.select(id)
}
toggleAll(value) {
if (value === true) {
this.setState({
pickedColors: this.props.baseProduct.variations.filter(p => p.type === 'color'),
})
} else {
this.setState({ pickedColors: [] })
}
}
setFirstColor() {
if (this.state.pickedColors.length > 0) {
this.props.setVariation(this.state.pickedColors[0])
}
}
render() {
if (this.state.error) {
return (
<GeneratorError
showBP={this.props.showBP}
reset={this.productPending}
/>
)
}
if (this.state.done) {
return (
<GeneratorProgress
active
showBP={this.props.showBP}
reset={this.productPending}
/>
)
}
if (this.props.product) {
return (
<GeneratorFlow>
<FullDesignSelector
designs={this.props.designs}
select={this.test}
addedDesigns={this.props.addedDesigns}
getImage={this.props.getImage}
removeDesign={this.props.removeDesign}
active
printingZone={this.props.printingZone}
setStep={this.setStep}
showBP={this.showBP}
showDS={this.props.showDS}
setKey={this.setKey}
/>
<ColorPicker
baseProduct={this.props.baseProduct}
product={this.props.product}
picked={this.state.pickedColors}
toggleColor={this.toggleColor}
variation={this.props.variation}
selectAll={this.toggleAll}
toggleFirstColor={this.props.toggleFirstColor}
setVariation={this.props.setVariation}
selectedColor={
this.props.variation ? this.props.variation.value : null
}
setPreviewColor={this.props.setVariation}
/>
<BaseProductPreview
addedDesigns={this.props.addedDesigns}
size={this.props.size}
shop={this.props.shop}
printingZone={this.props.printingZone}
picked={this.state.pickedColors}
previews={this.props.previews}
product={this.props.product}
setDone={this.productCreated}
baseProduct={this.getBaseProd()}
displaySuccess={this.props.displaySuccess}
generatorError={this.displayError}
status='edition'
setKey={this.setKey}
products={this.props.products}
productLoading={this.props.productLoading}
/>
</GeneratorFlow>
)
}
return (
<GeneratorFlow>
<ColorPicker
picked={this.state.pickedColors}
toggleColor={this.toggleColor}
baseProduct={this.props.baseProduct}
toggleFirstColor={this.setFirstColor}
variation={this.props.variation}
selectAll={this.toggleAll}
setVariation={this.props.setVariation}
selectedColor={
this.props.variation ? this.props.variation.value : null
}
setPreviewColor={this.props.setVariation}
/>
<FullDesignSelector
designs={this.props.designs}
select={this.props.select}
addedDesigns={this.props.addedDesigns}
getImage={this.props.getImage}
printingZone={this.props.printingZone}
removeDesign={this.props.removeDesign}
active
setStep={this.setStep}
showBP={this.showBP}
showDS={this.props.showDS}
setKey={this.setKey}
/>
<BaseProductPreview
addedDesigns={this.props.addedDesigns}
baseProduct={this.props.baseProduct}
generatorError={this.displayError}
size={this.props.size}
displaySuccess={this.props.displaySuccess}
shop={this.props.shop}
picked={this.state.pickedColors}
setDone={this.productCreated}
printingZone={this.props.printingZone}
previews={this.props.previews}
setPreview={this.props.setPreview}
status='creation'
setStep={this.setStep}
products={this.props.products}
productLoading={this.props.productLoading}
/>
</GeneratorFlow>
)
}
}
And here is the only part thst uses this prop in the child
import React, { Component } from 'react'
import styled from 'styled-components'
import toPx from 'unit-to-px'
import _ from 'lodash'
import { LocalForm, Control } from 'react-redux-form'
import { withRouter } from 'react-router-dom'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { toast } from 'react-toastify'
import { Input, Select, Icon, Tooltip } from 'antd'
import s3 from '../../../../../services/s3'
import theme from '../../../../../theme/theme'
import Alert from '../../../../../components/Alert'
import { createProduct, modifyProduct } from '../../../../../modules/products'
// import ProductImage from '../../../../../components/ProductImage'
class BaseProductPreview extends Component {
constructor(props) {
super(props)
let colors
if (props.product) {
colors = Object.assign([], props.product.variations.filter(v => v.type === 'color'))
} else {
colors = []
}
this.state = {
name: props.product ? props.product.name : '',
displayDescription: props.product ? Object.assign({}, props.product.displayDescription) : {},
collections: (props.product && props.product.collections) ? props.product.collections : [],
pricing: props.product ? Object.assign({}, props.product.pricing) : { margin: 0 },
elevdone: false,
i: 0,
colors,
}
this.createInnerProduct = this.createInnerProduct.bind(this)
this.getPrice = this.getPrice.bind(this)
}
oneColor() {
if (this.props.baseProduct.variations && this.state.colors) {
let colorAlert
if (this.state.colorAlertShown) {
colorAlert = <Alert message='Choisissez au moins une couleur' type='error' />
}
const colorsBp = this.props.baseProduct.variations.filter(v => v.type === 'color')
if (colorsBp.length <= 1) {
return ''
}
return (
<div>
<p>Choix de couleur :</p>
{ colorAlert }
<span
className='bullet-color'
>
{this.getColorsRef(this.props.baseProduct).map(value =>
(<div
onClick={() => { this.toggleColor(value) }}
className={this.colorIsInProduct(value)}
style={{ backgroundColor: value }}
/>))}
</span>
</div>)
}
return null
}
getColorsRef() {
return this.props.baseProduct.variations.filter(v => v.type === 'color').map(a => a.value)
}
colorIsInProduct(couleur) {
// true/false
let active
if (this.state.colors.find(v => v.value === couleur)) {
active = 'active-color'
}
return active
}
toggleColor(couleur) {
// const item = this.state.item
const colors = this.state.colors
// si on a deja la couleur dans le produit on l'enlève
if (colors.find(v => v.value === couleur) && colors.length > 1) {
// je retire cette couleur des varaitions de mon produits
const index = colors.indexOf(colors.find(v => v.value === couleur))
colors.splice(index, 1)
} else if (colors.find(v => v.value === couleur)) {
this.setState({ colorAlertShown: true })
} else {
// on va chercher la variation couleur corespondante
// dans le base product et on la copie dans le product
this.setState({ colorAlertShown: false })
colors.push(this.props.baseProduct.variations.find(v => v.value === couleur))
}
this.setState({ colors })
// TODO on change la couleur du mockup
}
getJsonsObjects(printingZones) {
// INITIATE EMPTY JSON OBJECT
const jsonsArray = {}
// GET CURRENT CANVAS
printingZones.map((item) => {
const y = document.getElementById(`${item}-canvas`).fabric
const helper = _.filter(y.getObjects(), { clipFor: 'layer' })[0]
if (helper) {
helper.set({ stroke: 'transparent' })
}
jsonsArray[item] = y.toJSON(['height'])
})
return jsonsArray
}
getCustomizationPrice() {
let customizationPrice = 0
Object.keys(this.props.baseProduct.printingZone).map((item) => {
const y = document.getElementById(`${item}-canvas`).fabric
const items = y.getObjects()
if (items.length > 1) {
customizationPrice = customizationPrice + 5
}
})
customizationPrice = customizationPrice - 5
if (customizationPrice < 0) {
customizationPrice = 0
}
return customizationPrice
}
getAction() {
return (<p>Créer mon produit</p>)
}
marginValidation(value) {
let returned_value = value
if (value == '') {
returned_value = 0
}
if (!value) {
returned_value = 0
} else if (value > 100) {
// TODO Show moreThan100Alert
returned_value = 100
}
const pricing = Object.assign({}, this.state.pricing, { margin: returned_value })
this.setState({ pricing })
}
validForm() {
if (this.state.name && this.props.picked.length > 0 && this.state.pricing.margin >= 0 && this.props.addedDesigns.length > 0) {
return false
}
return true
}
getPrice() {
const position_print = this.props.addedDesigns.map(d => {
return d.position
})
// uniq(position_print)
const count = []
position_print.map((position) => {
if (count.indexOf(position) === -1) {
count.push(position)
}
})
if (count.length <= 1) {
return (
<div>
<p className='price'>Cout de production <span>{this.props.baseProduct.unitPrice} €</span></p>
<div className='price-marge'>Vos bénéfices <span className='requiredField2'>*</span>
<Control.text
component={Input}
className='inputMarge'
model='.margin'
value={this.state.pricing.margin}
onChange={(e) => {
this.marginValidation(e.target.value.replace(',', '.'))
}}
/>
</div>
<hr />
<div className='price-total'>
{`
${parseFloat(this.props.baseProduct.unitPrice)
+
parseFloat(this.state.pricing.margin)} €`}
</div>
</div>
)
}
if (count.length > 1) {
return (
<div>
<p className='price'>Cout de production <span>{this.props.baseProduct.unitPrice} €</span></p>
<p className='price'>Impression supplémentaire <span>5 €</span></p>
<div className='price-marge'>Vos bénéfices <span className='requiredField2'>*</span>
<Control.text
component={Input}
className='inputMarge'
model='.margin'
value={this.state.pricing.margin}
onChange={(e) => {
this.marginValidation(e.target.value.replace(',', '.'))
}}
/>
</div>
<hr />
<div className='price-total'>
{`
${parseFloat(this.props.baseProduct.unitPrice)
+
parseFloat(this.state.pricing.margin) + parseFloat(5)} €`}
</div>
</div>
)
}
return null
}
getCategory() {
if (this.props.baseProduct.category.fr[0] === 'Homme' && this.props.baseProduct.category.fr[1] === 'Femme') {
return (<span>Unisex</span>)
}
if (this.props.baseProduct.category.fr[0] === 'Homme') {
return (<span>Homme</span>)
}
if (this.props.baseProduct.category.fr[0] === 'Femme') {
return (<span>Femme</span>)
}
return null
}
showElevio() {
if (this.state.i < 5) {
this.state.i = this.state.i + 1
setTimeout(() => {
if (this.props.productLoading.loading === true || this.props.products.length === 0) {
if (this.props.products.length === 0 && this.state.elevdone === false) {
return (
window._elev.openArticle(263),
this.setState({ elevdone: true })
)
} return null
}
if (this.props.productLoading.loading === false) {
this.showElevio()
}
return null
}, 500)
} return null
}
render() {
const { Option } = Select
const children = []
if (this.props.shop.settings.collections) {
this.props.shop.settings.collections.map((collec, i) => {
children.push(<Option key={collec.name ? collec.name : i}>{collec.name}</Option>)
return null
})
}
this.showElevio()
return (
<StyledBaseProductPreview>
<h2>Description</h2>
<LocalForm
onSubmit={() => this.createInnerProduct()}
>
<div className='form-step'>
<p className='advice-name'>
<Tooltip title='Figurera sur la fiche produit'>
<span>{this.props.baseProduct.subCategory.fr} {this.getCategory()}</span>
</Tooltip>
</p>
<p>Nom <span className='requiredField'>*</span></p>
<Control.text
component={Input}
model='.name'
placeholder='Nom du produit'
value={this.state.name}
onChange={(e) => {
this.setState({ name: e.target.value })
}}
/>
</div>
<div className='form-step'>
<p>Description</p>
<Control.textarea
className='productDescription'
model='.displayDescription'
placeholder='Description du produit'
value={this.state.displayDescription.fr}
onChange={(e) => {
const new_item = Object.assign({}, this.state.displayDescription)
new_item.fr = e.target.value
this.setState({ displayDescription: new_item })
}}
/>
</div>
<div className='form-step'>
<p>Collection(s)</p>
<Select
mode='multiple'
className='styledSelect'
placeholder='Pas de collection'
notFoundContent='Pas de collection'
value={this.state.collections}
style={{ width: '100%' }}
onSearch={(e) => {
this.setState({ toCreate: e })
}}
onChange={(e) => {
this.setState({ collections: e })
}}
>
{children}
</Select>
</div>
<div className='form-step pricingForm'>
<h2>Prix </h2>
<hr />
{this.getPrice()}
</div>
<Crumpet type='submit' className='superCrumpet' disabled={this.validForm()}>
{this.getAction()}
</Crumpet>
</LocalForm>
</StyledBaseProductPreview>
)
}
}
const mapStateToProps = (state, ownProps) => {
console.log(state); // state
console.log(ownProps); // undefined
return({
user: state.user,
addedDesigns: ownProps.addedDesigns,
})
}
const mapDispatchToProps = dispatch => bindActionCreators({
createProduct,
modifyProduct,
}, dispatch)
export default connect(
mapStateToProps,
mapDispatchToProps,
)(BaseProductPreview)
When inspecting these elements, I can see the parent getting updated :
And now, the funny part: when parent props get updated, the first two child component props are updated as well, but BaseProductPreview doesn't !
However, this gets updated as soon as I change the state of the child component.
How comes so ? How can the state update the component props ?

React only act on state not on props. whenever you change state UI gets update with latest changes. bind your props to state in child component and use componentWillReceiveProps(props) to change child state when props get updated in parent component.

Well the only solution I found was to connect a higher component with redux, so that none of the children were redux-related anymore, and then pass the reducer function through props to that child.
Without redux, my component gets updated properly.

Related

why dropdown in tables cell closes when the dropdowns page changes (kendoreact)

i have a grid with kendoreact that has a dropdown in its cell. i add a pager to the dropdown. but when i click on the pages, the dropdown close.
i have the same combobox in the form and it works good.
i tried a lot and worked on the pager and combobox props. but it was useless. perhaps its a behaviour from the grid. please help
import React, { useRef } from "react";
import { ComboBox } from "#progress/kendo-react-dropdowns";
import { filterBy } from "#progress/kendo-data-query";
import { Pager } from "#progress/kendo-react-data-tools";
import {
IntlProvider,
load,
LocalizationProvider,
loadMessages,
} from "#progress/kendo-react-intl";
import faMessages from "../../../../common/fa.json";
import persianJs from "persianjs";
// import Combobox from "../../../RPKCustomComponent/Combobox";
loadMessages(faMessages, "fa-IR");
const selectField = "selected";
const expandField = "expanded";
const dataItemKey = "value";
const textField = "label";
const subItemsField = "items";
const fields = {
selectField,
expandField,
dataItemKey,
subItemsField,
};
const initialType = "numeric";
const initialPageState = {
skip: 0,
take: 10,
total: 0,
buttonCount: 5,
type: initialType,
info: true,
// pageSizes: true,
previousNext: true,
responsive: true,
};
export default class ComboBoxCell extends React.Component {
state = {
data: [],
pageState: initialPageState,
take: 10,
skip: 0,
mammad: false,
};
handlepageChange = async (event) => {
// event.syntheticEvent.isDefaultPrevented();
// await this.setState({ skip: event.skip, take: event.take, mammad: true });
await this.props.getCombo({
id: this.props.dataItem.Id,
pageIndex: event.skip/10,
pageSize: 10,
search: "",
});
this.setState({mammad:true})
};
handleChange = (e) => {
this.props.onChange({
dataItem: this.props.dataItem,
field: this.props.field,
syntheticEvent: e.syntheticEvent,
value: e.target.value,
});
this.setState({mammad:true})
};
handleOnClick = async (e) => {
setTimeout(async () => {
if (!this.props.data && this.props.getCombo) {
await this.props.getCombo(true, this.state.skip / 10, 10, "");
}
}, 0);
this.setState({mammad:true})
};
componentDidMount() {
let dropdowntree = document.getElementById(`${this.props.id}`);
if (dropdowntree) {
dropdowntree.setAttribute("name", this.props.field);
}
this.textInput = React.createRef();
if (this.props.data?.List) {
let badData = this.props.data?.List.find((item) => {
if (item.value < 0 || item.label == null || item.label == undefined) {
return item;
}
});
if (badData) {
this.props.data.List.map((item) => {
if (item.label == null || item.label == undefined) {
item.label = "";
}
});
console.log("دیتای کمبو از سمت بک مشکل داره");
}
}
if (this.props.data?.List) {
let badData = this.props.data.List.find((item) => {
if (item.value < 0 || item.label == null || item.label == undefined) {
return item;
}
});
if (badData) {
this.props.data.List.map((item) => {
if (
item.label == null ||
item.label == undefined ||
item.label == false
) {
item.label = " ";
}
});
console.log("دیتای کمبو از سمت بک مشکل داره");
}
this.props.data.List.length > 0 &&
this.props.data.List.map(
(item) =>
(item.label =
item.label.length > 0 &&
persianJs(item.label)?.arabicChar()?._str)
);
}
this.setState({
data: this.props.data?.List,
pageState: {
...this.state.pageState,
total: this.props.data?.RecordCount ?? 0,
},
});
}
filterChange = (event) => {
this.setState({
data: this.filterData(event.filter),
});
};
filterData(filter) {
if (this.props.data?.List) {
const data = this.props.data?.List?.slice();
return filterBy(data, filter);
}
}
render() {
// let test=document.getElementsByClassName("comboFooterPageNumber")[0]
// console.log(test);
// document.getElementsByClassName("comboFooterPageNumber")[0]
// .addEventListener("click",(e)=>{
// console.log(e);
// });
// document
// .getElementsByClassName(this.props?.realurl)[0]
// .addEventListener("dblclick", this.AddInCell);
// console.log(this.state.skip);
console.log(this.state.mammad);
const { dataItem, field } = this.props;
const dataValue = dataItem[field] === null ? "" : dataItem[field];
const dataLableValue =
dataItem[field] === null ? "" : dataItem[field]?.label;
let dropValue = this.props.data?.List
? this.props.data?.List.find((c) => c.value == dataValue)
: null;
let dropLabel = this.props.data?.List
? this.props.data?.List.find((c) => c.value == dataValue)?.label
: null;
const listNoDataRender = (element) => {
const noData = (
<h4
style={{
fontSize: "1em",
}}
>
<span
className="k-icon k-i-warning"
style={{
fontSize: "1.5em",
}}
/>
<br />
<br />
موردی یافت نشد!
</h4>
);
return React.cloneElement(element, { ...element.props }, noData);
};
return (
<td className="cell-input">
{dataItem.inEdit && this.props.editable ? (
<ComboBox
{...this.props}
data={this.state.data ?? []}
onChange={this.handleChange}
textField={textField}
dataItemKey={dataItemKey}
filterable={true}
opened={this.state.mammad}
closed={!this.state.mammad}
onFilterChange={this.filterChange}
required={this.props.required}
onOpen={this.handleOnClick}
value={dropValue ?? dataValue}
listNoDataRender={listNoDataRender}
ariaLabelledBy={this.props.ariaLabelledBy ?? ""}
name={this.props.field}
footer={
// (!this.props.clientSide || this.props.allowNewForm) && (
<div>
{/* {this.props.allowNewForm && (
<>
<span className="comboFooter"></span>
<p onClick={others.setshowmodal}>افزودن گزینه جدید</p>
</>
)} */}
{/* {!this.props.clientSide && ( */}
<div className="comboFooterPageNumber">
<LocalizationProvider language="fa">
<Pager
skip={this.state.skip}
take={this.state.take}
total={this.state.pageState.total}
buttonCount={this.state.pageState.buttonCount}
info={this.state.pageState.info}
type={this.state.pageState.type}
previousNext={this.state.pageState.previousNext}
onPageChange={this.handlepageChange}
ref={this.textInput}
/>
</LocalizationProvider>
</div>
{/* )} */}
</div>
// )
}
/>
) : (
dropLabel ?? dataLableValue
)}
</td>
);
}
}

Property 'X' does not exist on type 'IntrinsicAttributes & InferPropsInner

I am refactoring my .js file into .tsx in the code below
import React, { useEffect, useState } from 'react'
import PropTypes from 'prop-types'
import { checkMobile } from '../../utils/common'
import { animateScroll as scroll } from 'react-scroll'
import ErrorBoundary from '../../components/error-boundary'
import Section1 from './section1'
import Section2 from './section2'
import Section3 from './section3'
import Section4 from './section4'
import Section5 from './section5'
import Section6 from './section6'
import Section7 from './section7'
export default function Main (props) {
const {
bannerData
} = props
const [currentPage, setCurrentPage] = useState(0)
const [isMobile, setIsMobile] = useState(false)
const mainScrollFunc = () => {
document.querySelector('header').classList.add('has-bg')
if (document.querySelector('.mainScrollEvent')) {
const scrollPosition = (document.body.scrollTop || document.documentElement.scrollTop) - (window.innerHeight / 1.5)
const mainSections = document.querySelectorAll('.main-section')
console.log('mainSections[0]', mainSections[0])
const paddingTop = 90
let toIndex = 0
if (scrollPosition <= (mainSections[0] as HTMLElement).offsetTop - paddingTop) {
toIndex = 0
} else if (scrollPosition <= (mainSections[1] as HTMLElement).offsetTop - paddingTop) {
toIndex = 1
} else if (scrollPosition <= (mainSections[2] as HTMLElement).offsetTop - paddingTop) {
toIndex = 2
} else if (scrollPosition <= (mainSections[3] as HTMLElement).offsetTop - paddingTop) {
toIndex = 3
} else if (scrollPosition <= (mainSections[4] as HTMLElement).offsetTop - paddingTop) {
toIndex = 4
} else if (scrollPosition <= (mainSections[5] as HTMLElement).offsetTop - paddingTop) {
toIndex = 5
} else if (scrollPosition <= (mainSections[6] as HTMLElement).offsetTop - paddingTop) {
toIndex = 6
}
for (let i = 0; i < 7; i++) {
document.querySelectorAll('.main_pager_button')[i].classList.remove('selected')
}
document.querySelector('.pagerButton' + toIndex).classList.add('selected')
if (toIndex === 0) {
if (document.querySelector('.top-banner')) {
document.querySelector('.top-banner').classList.add('is-active')
document.body.classList.add('has-banner')
}
} else {
if (document.querySelector('.top-banner')) {
document.querySelector('.top-banner').classList.remove('is-active')
document.body.classList.remove('has-banner')
}
}
setCurrentPage(toIndex)
}
}
const onScroll = () => {
const scrTop = document.body.scrollTop || document.documentElement.scrollTop
const windowHeight = window.innerHeight
const scrollPoint = windowHeight - 150
if (scrollPoint < scrTop) {
if (document.querySelector('.top-banner')) {
document.querySelector('.top-banner').classList.remove('is-active')
document.body.classList.remove('has-banner')
}
} else {
if (document.querySelector('.top-banner')) {
document.querySelector('.top-banner').classList.add('is-active')
document.body.classList.add('has-banner')
}
}
if (document.body.classList.contains('is-active')) {
const bodyTop = document.body.style.top.replace('px', '')
const mainSection1 = document.querySelector<HTMLElement>('.main-section.visual').offsetHeight - 150
const header = document.querySelector('header')
if (Math.abs(parseInt(bodyTop)) > mainSection1) {
if (document.querySelector('.top-banner')) {
document.querySelector('.top-banner').classList.remove('is-active')
document.body.classList.remove('has-banner')
}
if (header.classList.contains('is-white')) {
document.querySelector('header').classList.remove('is-white')
document.querySelector('header').classList.add('has-bg')
document.querySelector('header').classList.add('has-white')
}
}
}
}
const toMove = (e) => {
if (e.target.classList[0] === 'main_pager_button') {
e.preventDefault()
const href = e.target.getAttribute('href')
const offsetTop = document.querySelector(href).offsetTop
scroll.scrollTo(offsetTop, { duration: 500, smooth: 'easeInOut' })
}
}
useEffect(() => {
if (typeof window !== 'undefined') {
setIsMobile(!!checkMobile(window.innerWidth))
if (document.querySelector('.mainScrollEvent')) {
if (checkMobile(window.innerWidth)) {
window.addEventListener('scroll', onScroll)
} else {
window.addEventListener('scroll', mainScrollFunc)
}
}
}
return () => {
if (checkMobile(window.innerWidth)) {
window.removeEventListener('scroll', onScroll)
}
}
}, [])
return (
<>
<div id="contentsWrap" className="contents-wrap mainScrollEvent">
<Section1 isMobile={isMobile} bannerData={bannerData} />
<Section2 currentPage={currentPage}/>
<Section3 />
<Section4 isMobile={isMobile} currentPage={currentPage}/>
<Section5 isMobile={isMobile} currentPage={currentPage} />
<ErrorBoundary>
<Section6 currentPage={currentPage} />
</ErrorBoundary>
<ErrorBoundary>
<Section7 isMobile={isMobile} currentPage={currentPage}/>
</ErrorBoundary>
<nav className="main_pager_box" onClick={toMove}>
</nav>
</div>
<button type='button' className='btn btn-hidden' onClick={() => {
scroll.scrollToTop({ duration: 500, smooth: 'easeInOut' })
}}>TOP</button>
</>
)
}
Main.propTypes = {
bannerData: PropTypes.array
}
I am getting the following error in one line
<Section1 isMobile={isMobile} bannerData={bannerData} />
The error states
Type '{ isMobile: boolean; bannerData: any; }' is not assignable to type 'IntrinsicAttributes & InferPropsInner<Pick<{ bannerData: Requireable<any[]>; }, never>> & Partial<InferPropsInner<Pick<{ bannerData: Requireable<any[]>; }, "bannerData">>>'.
Property 'isMobile' does not exist on type 'IntrinsicAttributes & InferPropsInner<Pick<{ bannerData: Requireable<any[]>; }, never>> & Partial<InferPropsInner<Pick<{ bannerData: Requireable<any[]>; }, "bannerData">>>'.ts(2322)
I believe this is because I am sending my isMobile state as my props. However, I don't understand why this error only occurs on Section1 and not the other Section4, Section5, or Section7 that have isMobile in their props.
I have tried adding isMobile into the const with bannerData, but then I get another error telling me that I cannot redeclare block-scoped variable isMobile.
How do I solve this error?
*** EDIT ***
As requested, below is my Section1 code as a .js file
import React, { useState } from 'react'
import Image from 'next/image'
import PropTypes from 'prop-types'
import Slider from 'react-slick'
import useSWR from 'swr'
import { AxiosService } from '../../utils/axios-service'
import { getCloundFrontUrl } from '../../utils/common'
const axios = AxiosService.create()
const bannerUrl = '/banners?display=true&_sort=displayOrder:ASC'
export default function Section1 (props) {
const { data: banners, error } = useSWR(bannerUrl, (url) => {
return axios.get(url).then(res => res.data)
}, {
initialData: props.bannerData
})
const [currentSlide, setCurrentSlide] = useState(0)
const settings = {
arrows: true,
infinite: true,
autoplay: true,
speed: 300,
autoplaySpeed: 3600,
slidesToShow: 1,
slidesToScroll: 1,
className: 'banner-list swiper-list',
pauseOnHover: false,
afterChange: (index) => {
setCurrentSlide(index)
}
}
if (!banners) {
return <div>배너 읽는 중</div>
}
return (
<div id="visual" className="main-section visual">
<div className="main-section-content">
{/* <!-- s: slider--> */}
<div className="banner-list-wrap swiper-container">
<Slider {...settings}>
{
banners.map(b => {
const linkProps = {
...(b.openNewTab && {
target: '_blank'
})
}
let imageUrl = ''
if (b.images && b.images.length > 0) {
imageUrl = getCloundFrontUrl(b.images[0].url)
}
return (
<div className="banner-item swiper-item" key={b.id}>
<div className="img">
<Image className="img-drawer" src={imageUrl ? getCloundFrontUrl(imageUrl) : '/'} alt={b.images[0]?.alternativeText} layout="fill" />
</div>
<div className="visual-info">
<pre className="title">{b.title}</pre>
{b.description && (<pre className="desc">{b.description}</pre>)}
{b.linkUrl && (<a href={b.linkUrl} className="btn-go-detail" {...linkProps}>자세히보기</a>)}
</div>
</div>
)
})
}
</Slider>
<div className="slider-assets">
<div className="swiper-paging swiper-pagination-fraction">
<span className="swiper-pagination-current">{currentSlide + 1}</span>
<span className="swiper-pagination-slash">/</span>
<span className="swiper-pagination-total">{banners.length}</span>
</div>
</div>
</div>
{/* <!-- e: slider--> */}
</div>
</div>
)
}
Section1.propTypes = {
bannerData: PropTypes.array
}
I'm an idiot and isMobile is never used in Section1
If you want to pass isMobile is a prop of Section1, you need to update Section1.propTypes:
Section1.propTypes = {
bannerData: PropTypes.array,
isMobile: PropTypes.bool
}

How to render only 5 items in react autosuggest?

I'am using react autosuggest npm package to get the json data and display it. I want to display only 5 items. How to do it?
Form.js
import React from 'react'
import Autosuggest from 'react-autosuggest';
import cities from 'cities.json';
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
);
);
};
const getSuggestionValue = suggestion => suggestion.name;
const renderSuggestion = suggestion => (
<div>
{console.log('suggestion', suggestion)}
{suggestion.name}
</div>
);
class Form extends React.Component {
constructor() {
super();
this.state = {
value: '',
suggestions: []
};
}
onChange = (event, { newValue }) => {
this.setState({
value: newValue
});
};
onSuggestionsFetchRequested = ({ value }) => {
this.setState({
suggestions: getSuggestions(value)
});
};
onSuggestionsClearRequested = () => {
this.setState({
suggestions: []
});
};
render(){
const { value, suggestions } = this.state;
// Autosuggest will pass through all these props to the input.
const inputProps = {
placeholder: 'Search City...',
value,
onChange: this.onChange
};
return (
<div>
<Autosuggest
suggestions={suggestions}
onSuggestionsFetchRequested={this.onSuggestionsFetchRequested}
onSuggestionsClearRequested={this.onSuggestionsClearRequested}
getSuggestionValue={getSuggestionValue}
renderSuggestion={renderSuggestion}
inputProps={inputProps}
/>
<br/>
</div>
)
}
}
export default Form;
I want to render only 5 items, otherwise, computer hangs while loading huge data. Is there any other autocomplete react npm package, since I want only cities and country list. i.e when city is inputted, automatically the city name must be suggested with its relevant country.Any solution or suggestion highly appreciated. Thanks in advance
i modified you're getSuggestions() method a little i guess this should work for you.
const getSuggestions = value => {
const inputValue = value.trim().toLowerCase();
const inputLength = inputValue.length;
// Here I get data from cities.json
return inputLength === 0 ? [] : cities.filter(lang =>
lang.name.toLowerCase().slice(0, inputLength) === inputValue
).slice(0,5);
};
Use the Slice method with start index and last Index
suggestions={suggestions.slice(0, 5)}
import {
React
,Avatar
,axiosbase
} from '../../import-files';
import Autosuggest from 'react-autosuggest';
import './autosuggest.css';
import { withStyles } from '#material-ui/core/styles';
import TextField from '#material-ui/core/TextField';
import Paper from '#material-ui/core/Paper';
import MenuItem from '#material-ui/core/MenuItem';
let suggestions = [ { label: 'Afghanistan' } ];
function renderInputComponent(inputProps) {
const { classes, inputRef = () => {}, ref, ...other } = inputProps;
return (
<TextField
className={classes.textField}
fullWidth
variant="outlined"
InputProps={{
inputRef: node => {
ref(node);
inputRef(node);
},
classes: {
input: classes.input,
},
}}
{...other}
/>
);
}
function renderSuggestion(suggestion, { query, isHighlighted }) {
return (
<MenuItem selected={isHighlighted} component="div">
<div>
<strong key={String(suggestion.id)} style={{ fontWeight: 300 }}>
<span className="sugg-option">
<span className="icon-wrap">
<Avatar src={suggestion.Poster}></Avatar>
</span>
<span className="name">
{suggestion.Title}
</span>
</span>
</strong>
</div>
</MenuItem>
);
}
function initSuggestions(value) {
suggestions = value;
}
function getSuggestionValue(suggestion) {
return suggestion.Title;
}
function onSuggestionSelected(event, { suggestion, suggestionValue, suggestionIndex, sectionIndex, method }) {
console.log('HandleSuggestion() '+suggestionValue);
}
const styles = theme => ({
root: {
height: 50,
flexGrow: 1,
},
container: {
position: 'relative',
},
suggestionsContainerOpen: {
position: 'absolute',
zIndex: 998,
marginTop: theme.spacing.unit,
left: 0,
right: 0,
overflowY: 'scroll',
maxHeight:'376%'
},
suggestion: {
display: 'block',
},
suggestionsList: {
margin: 0,
padding: 0,
listStyleType: 'none',
},
divider: {
height: theme.spacing.unit * 2,
},
});
class IntegrationAutosuggest extends React.Component {
state = {
single: '',
popper: '',
suggestions: [],
};
componentDidMount() {
initSuggestions(suggestions);
}
// Filter logic
getSuggestions = async (value) => {
const inputValue = value.trim().toLowerCase();
var _filter = JSON.stringify({
filter : inputValue,
});
return await axiosbase.post(`${apiCall}`, _filter);
};
handleSuggestionsFetchRequested = ({ value }) => {
this.getSuggestions(value)
.then(data => {
if (data.Error) {
this.setState({
suggestions: []
});
} else {
const responseData = [];
data.data.itemsList.map((item, i) => {
let File = {
id: item.idEnc,
Title: item.englishFullName +' '+item.arabicFullName,
englishFullName: item.englishFullName,
arabicFullName: item.arabicFullName,
Poster: item.photoPath,
}
responseData.push(File);
});
this.setState({
suggestions: responseData
});
}
})
};
handleSuggestionsClearRequested = () => {
this.setState({
suggestions: [],
});
};
handleChange = name => (event, { newValue }) => {
this.setState({
[name]: newValue,
});
if(event.type=='click'){
if(typeof this.props.handleOrderUserFirstNameChange === "function"){
this.props.handleOrderUserFirstNameChange(newValue);
}
this.state.suggestions.filter(f=>f.Title===newValue).map((item, i) => {
//id
//Title
// Poster
if(typeof this.props.handleUserIDChange === "function"){
this.props.handleUserIDChange(item.id);
}
});
}
};
render() {
const { classes } = this.props;
// console.log('Re-render!!');
// console.log(this.props);
// console.log(this.state.suggestions);
const autosuggestProps = {
renderInputComponent,
suggestions: this.state.suggestions,
onSuggestionsFetchRequested: this.handleSuggestionsFetchRequested,
onSuggestionsClearRequested: this.handleSuggestionsClearRequested,
onSuggestionSelected: this.props.onSelect,
getSuggestionValue,
renderSuggestion,
};
return (
<div className={classes.root}>
<Autosuggest
{...autosuggestProps}
inputProps={{
classes,
placeholder: this.props.placeHolder,
value: this.state.single,
onChange: this.handleChange('single'),
}}
theme={{
container: classes.container,
suggestionsContainerOpen: classes.suggestionsContainerOpen,
suggestionsList: classes.suggestionsList,
suggestion: classes.suggestion,
}}
renderSuggestionsContainer={options => (
<Paper {...options.containerProps} square>
{options.children}
</Paper>
)}
/>
<div className={classes.divider} />
</div>
);
}
}
export default withStyles(styles)(IntegrationAutosuggest);

React-Select upgraded from 1.x to 3.0.4 - Selected value not shown

I am a bit new in React and i am trying to upgrading react from old version to 16.9.
Everything works great but the following component that i had to upgrade to version 3.0.4.
The problem is that when i select a value, it's selected but i don't see the selected option on the screen and i see only the default placeholder.
i found few answers that explaining that i have to set the value using the full object and as per my understanding i am doing so.
Can someone help me to find the problem?
// #flow
import React, { Component } from "react";
import ReactSelect from "react-select";
import { isNil } from "lodash";
import type { FormProps } from "redux-form";
import cx from "classnames";
import { getClassName, addModifierTo } from "ui-kit/utils/component";
import { injectIntl, FormattedMessage } from "react-intl";
/* import "react-select/dist/react-select.css"; */
import "./Select.scss";
type Option = {
label: string,
value: string
}
type Props = {
name?: string,
options?: Array<Option>,
className?: string
} & FormProps;
type State = {
selectedOption: Object
}
const getInitOption = (multi, valueType) => (multi && valueType === "Array" ? [] : "");
class Select extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
selectedOption: this.getOptionFromPropValue(),
openUp: false
};
}
componentDidMount() {
const { defaultValue, input } = this.props;
if (input && defaultValue) {
input.onChange(defaultValue);
}
}
getOptionFromPropValue(props: Props = this.props) {
const {
defaultValue,
input,
multi,
valueType = "String",
value: valueFromProp
} = props;
let value = "";
if (!isNil(defaultValue)) {
value = defaultValue;
}
if (input && !isNil(input.value)) {
({ value } = input);
}
else if (valueFromProp) {
value = valueFromProp;
}
let options;
if (multi) {
if (valueType === "String" || typeof value === "string") {
value = value.split(",");
}
options = value.map(valueItem => ({ value: valueItem }));
} else {
options = [{ value }];
}
if (props.options) {
options = options.map((option) => {
const sameOption = props.options.find(item => item.value === option.value);
if (sameOption) {
return sameOption;
}
return option.value !== "" ? option : null;
});
}
return multi ? options : options[0];
}
initialized: false
UNSAFE_componentWillReceiveProps(nextProps) {
const {
loadedLabel, input, multi, valueType
} = nextProps;
if (!this.initialized) {
this.setState({ selectedOption: this.getOptionFromPropValue(nextProps) });
this.initialized = true;
}
if (this.selectedOption && !this.selectedOption.label && loadedLabel) {
this.setState(prevState => ({ selectedOption: { ...prevState.selectedOption, label: loadedLabel } }));
}
if (input && !input.value) {
this.setState({ selectedOption: getInitOption(multi, valueType) });
}
}
render() {
const {
className,
name,
label,
simple,
creatable = false,
asyncLoad = false,
input,
hasBorder = true,
errorOffset = false,
meta = {},
onChange: onChangeEvent,
onChangeReplace,
initialized,
defaultValue,
multi,
valueType = "String",
maxHeight,
...props
} = this.props;
const msg = meta.error || meta.warning;
let Tag;
if (asyncLoad) {
Tag = creatable ? ReactSelect.AsyncCreatable : ReactSelect.Async;
} else {
Tag = creatable ? ReactSelect.Creatable : ReactSelect;
}
const onChange = onChangeReplace || ((selectedOption) => {
if (!selectedOption) {
selectedOption = { value: "" };
}
let value;
if (multi && Array.isArray(selectedOption)) {
value = selectedOption.map(({ value: valueItem }) => valueItem);
if (valueType === "String") {
value = value.join(",");
}
} else {
({ value } = selectedOption);
}
if (input) {
input.onChange(value);
}
if (onChangeEvent) onChangeEvent({ target: { name, value } });
this.setState({ selectedOption });
});
// for fix bug with losing value on Blur (https://github.com/erikras/redux-form/issues/1185)
const onBlur = () => input && this.state.selectedOption && input.onBlur(this.state.selectedOption.value);
const onOpenHandler = () => {
if (!isNil(this.elDOM)) {
let inputEl = this.elDOM.input;
if (!isNil(inputEl) && !(inputEl instanceof window.Element)) {
inputEl = inputEl.input;
}
if (!isNil(inputEl) && !isNil(this.elDOM.menuContainer)) {
const rect = inputEl.getBoundingClientRect();
const menuRect = this.elDOM.menuContainer.getBoundingClientRect();
const bottomDistance = window.innerHeight - rect.bottom;
const openUp = bottomDistance < (menuRect.height + 20);
this.setState({ openUp }, () => {
if (openUp && rect.top < menuRect.height) {
window.scrollTo(0, window.scrollY - (menuRect.height - rect.top));
}
});
}
}
};
const ccn = getClassName("Select");
const modify = addModifierTo(ccn());
const modifyWrap = addModifierTo(ccn("wrap"));
console.log(this.state.selectedOption);
// className "Select" is already present in Tag
return (
<div
className={cx(
ccn("wrap"),
errorOffset && modifyWrap("error-offset"),
className,
meta.visited && meta.invalid && modify("invalid"),
this.state.openUp && modify("up")
)}
>
{label && <div className={ccn("label")}>{label}</div>}
<Tag
className={cx(
simple && modify("simple"),
!hasBorder && modify("no-border"),
)}
style={{ maxHeight }}
name={name}
multi={multi}
{...input}
clearable={false}
backspaceRemoves={false}
autosize={simple || false}
value={this.state.selectedOption}
onChange={onChange}
onBlur={onBlur.bind(this)}
onOpen={onOpenHandler}
ref={(el) => { this.elDOM = el; }}
placeholder=""
noResultsText={<FormattedMessage id="select.noResultsText" defaultMessage="No results found" />}
{...props}
/>
{meta.visited && msg && <div className={ccn("validationMsg")}>{msg}</div>}
</div>
);
}
}
export default injectIntl(Select);
I think the react version for React-Select is 16.8.
https://github.com/JedWatson/react-select/issues/3585

Cannot Find what is causing this : Warning: setState(...): Can only update a mounted or mounting component

So after looking over many different questions asking the about this warning, I have found that there is not one single reason why this would be occurring making it difficult to infer a solution on my own code.
So here is my code incase anyone has another pair of eyes they can put on it and spot maybe why i would be getting this error.
This error occurs when not on first arrival of the component but after leaving and returning to it again.
I have a smart container and a dumb component set up so here is the container:
import React, { PropTypes } from 'react';
import { connect } from 'react-redux';
import { listOrders, listUseCases } from '../../actions/order';
import { storeWithExpiration } from '../../utils/common.js';
import OrdersIndex from './OrdersIndex';
export class OrdersIndexContainer extends React.Component {
static propTypes = {
account: PropTypes.object.isRequired,
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
listOrdersAction: PropTypes.func.isRequired,
listUseCasesAction: PropTypes.func.isRequired,
};
render() {
const { orders, platformMap, progress } = this.props;
return (
<div>
<OrdersIndex
orders={ orders }
platformMap={ platformMap }
progress={ progress }
/>
</div>
);
}
renderOrderIndex = () => {
}
componentWillMount = () => {
const { account, listOrdersAction, listUseCasesAction } = this.props;
const token = storeWithExpiration.get('token');
listOrdersAction(token);
listUseCasesAction(account.id, token);
}
}
function mapStateToProps(state) {
const { account, orderList, progress } = state;
const orders = orderList.get('orders');
const platformMap = orderList.get('platformMap');
return { account, platformMap, orders, progress };
}
export default connect(mapStateToProps, {
listOrdersAction: listOrders,
listUseCasesAction: listUseCases,
})(OrdersIndexContainer);
And here is the dumb component:
import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import ReactDataGrid from 'react-data-grid';
import { Toolbar } from 'react-data-grid/addons';
import { Data } from 'react-data-grid/addons';
import moment from 'moment';
import { SIMPLE_DATE_FORMAT } from '../../config/app_config';
// import OrderWrapFormatter from './OrderWrapFormatter';
const TABLE_COLUMNS = [
{ key: 'cNumber', name: 'Customer #', width: 125 },
{ key: 'name', name: 'Name', width: 150 },
{ key: 'orderNumber', name: 'Order #', width: 90 },
{ key: 'platform', name: 'Platform' },
{ key: 'useCase', name: 'Use Case'/* , formatter: OrderWrapFormatter */ },
{ key: 'list', name: 'List' },
{ key: 'sku', name: 'SKU' },
{ key: 'startDate', name: 'Start Date' },
{ key: 'endDate', name: 'End Date' },
];
export default class OrdersIndex extends React.Component {
static propTypes = {
orders: PropTypes.object.isRequired,
platformMap: PropTypes.object.isRequired,
progress: PropTypes.number,
};
state = {
rows: [],
originalRows: [],
columns: TABLE_COLUMNS,
sortColumn: null,
sortDirection: null,
filters: {},
}
renderRows = (orders) => {
const _rows = [];
orders.map((o) => {
_rows.push({
key: o.order.id,
id: o.order.id,
cNumber: o.order.providerCustomerNumber,
name: o.order.company.name,
orderNumber: o.order.providerOrderNumber,
platform: o.platformUseCases[0].platform.description,
useCase: this.renderMulti(o.platformUseCases, 'useCase', 'description'),
list: this.renderMulti(o.listSKUs, 'dataSet', 'name'),
sku: this.renderMulti(o.listSKUs, 'fieldSet', 'name'),
startDate: moment(o.order.startDate).format(SIMPLE_DATE_FORMAT),
endDate: moment(o.order.endDate).format(SIMPLE_DATE_FORMAT),
});
return _rows;
});
return this.setState({
rows: _rows,
originalRows: _rows.slice(),
});
}
getRows = () => {
return Data.Selectors.getRows(this.state);
}
rowGetter = (rowIdx) => {
const rows = this.getRows();
return rows[rowIdx];
}
getSize = () => {
return this.getRows().length;
}
renderMulti = (multi, itemName, subItemName) => {
const objectArray = multi.map((object) => {
return object[itemName][subItemName];
});
return objectArray.join('\n');
}
handleGridSort = (sortColumn, sortDirection) => {
const { originalRows, rows } = this.state;
const comparer = (a, b) => {
if (sortDirection === 'ASC') {
return (a[sortColumn] > b[sortColumn]) ? 1 : -1;
}
else if (sortDirection === 'DESC') {
return (a[sortColumn] < b[sortColumn]) ? 1 : -1;
}
};
const newRows = sortDirection === 'NONE' ? originalRows.slice() : rows.sort(comparer);
this.setState({
rows: newRows,
});
}
handleRowUpdated = (e) => {
// merge updated row with current row and rerender by setting state
const { rows } = this.state;
Object.assign(rows[e.rowIdx], e.updated);
this.setState({
...rows,
});
}
handleFilterChange = (filter) => {
const { filters } = this.state;
const newFilters = Object.assign({}, filters);
if (filter.filterTerm) {
newFilters[filter.column.key] = filter;
}
else {
delete newFilters[filter.column.key];
}
this.setState({
filters: newFilters,
});
}
onClearFilters = () => {
// all filters removed
this.setState({
filters: {},
});
}
// Creates appropriate warnings to prevent entering
// the order form if the account is missing information
renderNotice = (message, buttonMessage, route) => {
return (
<div className="alert alert-warning">
<strong>Notice:</strong>
<p>{ message }</p>
<p>
<Link
to={ route }
className="btn btn-warning"
>
<i className='fa fa-plus'></i>
{ buttonMessage }
</Link>
</p>
</div>
);
}
render() {
const { platformMap, progress } = this.props;
const platformMessage = 'Your account is not associated with any platform use cases.' +
'You must select at least one use case before creating new orders.';
const platformButton = 'Add Use Cases';
const platformRoute = '/products';
return (
<div className="container">
<div className="row">
<div className="col-sm-12 col-md-8">
<h1>Orders</h1>
</div>
<div className="col-sm-12 col-md-4">
<span className="pull-right">
<Link
to="/orders/create/1"
className="btn btn-primary"
disabled
>
<i className='fa fa-plus'></i>Create New Order
</Link>
</span>
</div>
</div>
{ platformMap.size === 0 && progress === 0 ?
this.renderNotice(platformMessage, platformButton, platformRoute) : null }
<div className="row">
{ progress === 0 ?
<div className="col-md-12">
{ this.renderTable() }
</div> : null }
</div>
</div>
);
}
renderTable = () => {
const { orders } = this.props;
const { columns } = this.state;
return (
<div>
{ orders.size === 0 || orders === undefined ?
<p>Your account has no orders</p> :
<ReactDataGrid
onGridSort={ this.handleGridSort }
rowKey="key"
id="key"
columns={ columns }
rowGetter={ this.rowGetter }
rowsCount={ this.getSize() }
onRowUpdated={ this.handleRowUpdated }
toolbar={ <Toolbar enableFilter /> }
onAddFilter={ this.handleFilterChange }
onClearFilters={ this.onClearFilters }
minHeight={ 500 }
filterRowsButtonText="Search By Field"
/>
}
</div>
);
}
componentWillMount = () => {
const { orders } = this.props;
const columnArray =
TABLE_COLUMNS.map((c) => {
const copy = Object.assign({}, c);
copy.filterable = true;
copy.locked = true;
if (copy.key !== 'useCase') {
copy.sortable = true;
}
return copy;
});
this.setState({
columns: columnArray,
});
this.renderRows(orders);
}
componentWillReceiveProps = (nextProps) => {
const { orders } = nextProps;
if (orders.size > 0) {
this.renderRows(orders);
}
}
}
I understand this might be a lot but I cannot for the life of me determine what could be the cause. Thanks to anyone who takes a look.

Resources