React Native: render only once tab view - reactjs

i have been using this plugin react-native-tab-view and for my case i have 5 routes but all use the same component so its rendered five times the component and also have an api call that i have inside the component that its fired 5 times.So my question is if there is a way to render only the tab that i selected besides iam using the same component this is my code:
const FirstRoute = () => (
<View>
<PostsList />
</View>
);
const initialLayout = {
height: 0,
width: Dimensions.get('window').width,
};
class Home extends Component {
constructor() {
super();
this.state = {
isData: true,
index: 0,
routes: [
{ key: 'first', title: 'Todos' },
{ key: 'second', title: 'Encontrados' },
{ key: 'third', title: 'Perdidos' },
{ key: 'four', title: 'AdopciĆ³n' },
{ key: 'five', title: 'Seguidos' },
]
};
}
_renderTabBar = props => (
<TabBar
{...props}
scrollEnabled
indicatorStyle={styles.indicator}
style={styles.tabbar}
tabStyle={styles.tab}
labelStyle={styles.label}
/>
);
_renderScene = SceneMap({
first: FirstRoute,
second: FirstRoute,
third: FirstRoute,
four: FirstRoute,
five: FirstRoute
})
_handleIndexChange = index => {
this.props.selected_tab(index);
this.setState({
index,
});
}
render() {
return (
<TabView
navigationState={this.state}
renderTabBar={this._renderTabBar}
renderScene={this._renderScene}
onIndexChange={this._handleIndexChange}
initialLayout={initialLayout}
/>
)
}
}

Related

React Data Grid: Custom DropDown Editor: value is not getting updated. Grid is not getting enabled for editing

on react-data-grid 7.0.0-beta
I read through the most recent demos provided in git repo for react-data-grid and implemented a custom dropdown for my use case.
Dropdown seems to be working but it is not updating the grid data upon selection. The editable property doesn't seem to be working either.
test code is implemented here:
Sandbox: https://codesandbox.io/s/react-data-grid-custom-dropdown-editor-kcy5n
export const EntryCriteriaGrid = () => {
const columns = [
{
key: "r1",
name: "Criteria",
width: "50%",
resizable: true,
editable: true
},
{
key: "status",
name: "Status",
editor: DropdownCustomEditor,
editorOptions: {
editOnClick: true
},
editable: true
},
{ key: "tracker", name: "Tracker", editable: true }
];
const rows = [
{ r1: "data 1", status: "BLOCKED", tracker: "tracker 1" },
{ r1: "data 2", status: "PASS", tracker: "tracker 1" },
{ r1: "data 3", status: "ISSUE", tracker: "tracker 2" }
];
const [state, setState] = useState({ rows });
const onGridRowsUpdated = ({ fromRow, toRow, updated }) => {
setState((state) => {
const rows = state.rows.slice();
for (let i = fromRow; i <= toRow; i++) {
rows[i] = { ...rows[i], ...updated };
}
return { rows };
});
};
return (
<div>
<ReactDataGrid
columns={columns}
rows={state.rows}
rowsCount={3}
onGridRowsUpdated={onGridRowsUpdated}
enableCellSelect={true}
className="rdg-light"
/>
</div>
);
};
export default EntryCriteriaGrid;
import React, { Component } from "react";
import ReactDOM from "react-dom";
export default class DropdownCustomEditor extends Component {
constructor(props) {
super(props);
this.state = {
selected: ""
};
this.options = [
{ id: "blocked", value: "BLOCKED" },
{ id: "pass", value: "PASS" },
{ id: "issue", value: "ISSUE" },
{ id: "notStarted", value: "NOT STARTED" }
];
}
componentDidMount() {
if (this.props.row && this.props.row.status)
this.setState({ selected: this.props.row.status });
}
getValue = function () {
return { status: this.state.selected };
};
getInputNode() {
return ReactDOM.findDOMNode(this).getElementsByTagName("select")[0];
}
update(e) {
this.setState({ selected: e.target.value });
this.props.onRowChange({ ...this.props.row, status: e.target.value }, true);
}
render() {
return (
<select
className="rdg-select-editor"
onChange={(e) => this.update(e)}
autoFocus
value={this.state.selected}
>
{this.options.map((elem) => {
return (
<option key={elem.id} value={elem.value}>
{elem.value}
</option>
);
})}
</select>
);
}
}
Just change your code as follows:
In DropdownCustomEditor component:
update(e) {
this.setState({ selected: e.target.value });
this.props.onRowChange({ ...this.props.row, status: e.target.value });
}
In EntryCriteriaGrid component
const onGridRowsUpdated = (rows) => {
setState({ rows });
};
and
<ReactDataGrid
columns={columns}
rows={state.rows}
rowsCount={3}
//onRowsUpdate={onGridRowsUpdated}
enableCellSelect={true}
className="rdg-light"
onRowsChange={(rows) => onGridRowsUpdated(rows)}
/>

State exists but not a function error happens. this.setState is not a function

State is existing but "not a function error" happens.
I am developing a component with React Tag.
The function is exists
I have no idea what it is wrong..
Error says
TypeError: this.setState is not a function
class ReagtTagSample extends Component {
constructor(props) {
super(props);
this.state = {
tags: [{ id: 'Yugoslavia', text: 'Yugoslavia' }, { id: 'India', text: 'India' }],
suggestions: [
{ id: "England", text: "England" },
{ id: "Mexico", text: "Mexico" },
],
};
handleAddition(tag) {
this.setState((state) => ({ tags: [...state.tags, tag] }));
}
handleDrag(tag, currPos, newPos) {
const tags = [...this.state.tags];
const newTags = tags.slice();
newTags.splice(currPos, 1);
newTags.splice(newPos, 0, tag);
this.setState({ tags: newTags });
}
render() {
const { test } = this.props;
const { tags, suggestions } = this.state;
<ReactTags
tags={tags}
suggestions={suggestions}
handleDelete={this.handleDelete}
handleAddition={this.handleAddition}
handleDrag={this.handleDrag}
delimiters={delimiters}
/>
handleAddition should be an arrow function to rebind this otherwise is not a class reference
handleAddition = (tag) => {
this.setState((state) => ({ tags: [...state.tags, tag] }));
}
same applies for handleDrag

Minimizing un-necessary re-renders in a large list React component tree

I am creating a large list with this accordion on React Native. The problem I face is the re-renders that happening in the renderItem function. When the input changes in the Product component whole component tree is re-rendered. Is there way to stop re-rendering the whole component tree for input changes on the product component with using React.memo or React.useMemo ?
const categories = [
{ id: 1, name: 'Category A' },
{ id: 2, name: 'Category B' },
{ id: 3, name: 'Category B' },
]
const products = [
{ id: 1, name: 'Product A', category: 1 },
{ id: 2, name: 'Product B', category: 1 },
{ id: 3, name: 'Product C', category: 2 },
{ id: 4, name: 'Product D', category: 2 },
{ id: 5, name: 'Product E', category: 3 },
]
const handleChange = (product, quantity) => {
console.log('handle change event fired');
};
const renderHeader = (category) => {
return (
<View>
<Text>{category.name}</Text>
</View>
);
};
const renderContent = (category) => {
const categoryProducts = products.filter(product => product.category_id === category.id);
const renderItem = (product) => {
return (
<Product
key={product.id}
product={product}
handleChange={handleChange}
/>
);
};
return (
<View>
{
categoryProducts.map(product => {
return (renderItem(product));
})
}
</View>
);
};
return (
<ScrollView>
<Accordion
sections={categories}
renderHeader={renderHeader}
renderContent={renderContent}
/>
</ScrollView>
);
The Product Compoenent
<View>
<Input
size="small"
keyboardType="number-pad"
onChangeText={(changedQuantity) => {
handleChange( product, changedQuantity);
}}
value={quantity}
/>
</View>

How to convert function component to class component in fluent UI?

I am creating multi select drop down in Office fabrics.I saw the code.It contain the functional component.I want to change in class component.and How can we store the selected options in state variable?
please guide me.I am new in spfx share-point.
Code given below:-
import * as React from 'react';
import { Dropdown, DropdownMenuItemType, IDropdownOption, IDropdownStyles } from 'office-ui-fabric-react/lib/Dropdown';
const dropdownStyles: Partial<IDropdownStyles> = { dropdown: { width: 300 } };
const DropdownControlledMultiExampleOptions = [
{ key: 'fruitsHeader', text: 'Fruits', itemType: DropdownMenuItemType.Header },
{ key: 'apple', text: 'Apple' },
{ key: 'banana', text: 'Banana' },
{ key: 'orange', text: 'Orange', disabled: true },
{ key: 'grape', text: 'Grape' },
{ key: 'divider_1', text: '-', itemType: DropdownMenuItemType.Divider },
{ key: 'vegetablesHeader', text: 'Vegetables', itemType: DropdownMenuItemType.Header },
{ key: 'broccoli', text: 'Broccoli' },
{ key: 'carrot', text: 'Carrot' },
{ key: 'lettuce', text: 'Lettuce' },
];
export const DropdownControlledMultiExample: React.FunctionComponent = () => {
const [selectedKeys, setSelectedKeys] = React.useState<string[]>([]);
const onChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
if (item) {
setSelectedKeys(
item.selected ? [...selectedKeys, item.key as string] : selectedKeys.filter(key => key !== item.key),
);
}
};
return (
<Dropdown
placeholder="Select options"
label="Multi-select controlled example"
selectedKeys={selectedKeys}
onChange={onChange}
multiSelect
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
/>
);
};
You can do the following:
export class DropdownControlledMultiExample extends React.Component {
state = {
selectedKeys: []
}
onChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
if (item) {
this.setState({
selectedKeys:
item.selected
? [...this.state.selectedKeys, item.key as string]
: this.state.selectedKeys.filter(key => key !== item.key),
});
}
};
render() {
return (
<Dropdown
placeholder="Select options"
label="Multi-select controlled example"
selectedKeys={this.state.selectedKeys}
onChange={this.onChange}
multiSelect
options={DropdownControlledMultiExampleOptions}
styles={dropdownStyles}
/>
);
}
};

How do you set the value of a TextField from Dropdown Selection?

In the following code, I was curious as to how you would set the value of the following TextField.
For this example, how do I set the TextField to the selected item in the Dropdown?
If the user selects "TOP LEVEL" in the Dropdown, then I want to populate the TextField to be "TOP LEVEL". The Dropdown is called ChildComponent
import * as React from "react";
import ChildComponent from './Operations/ChildComponent';
import { DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface ParentComponentState {
selectedItem?: { key: string | number | undefined };
value: {key: string};
}
export default class ParentComponent extends React.Component<{}, ParentComponentState> {
constructor(props, context) {
super(props, context);
}
public state: ParentComponentState = {
selectedItem: undefined,
value: undefined,
};
render(){
const { selectedItem } = this.state;
const options: IDropdownOption[] = [
{ key: 'blank', text: '' },
{ key: 'topLevelMake', text: 'Parents', itemType: DropdownMenuItemType.Header },
{ key: 'topLevel', text: 'TOP LEVEL' },
{ key: 'make', text: 'MAKE ITEM' },
{ key: 'divider_1', text: '-', itemType: DropdownMenuItemType.Divider },
{ key: 'Purchased', text: 'Purchases', itemType: DropdownMenuItemType.Header },
{ key: 'rawMaterial', text: 'RAW MATERIAL' },
{ key: 'buyItem', text: 'BUY ITEM' },
];
return(
<div>
<ChildComponent
options={options}
selectedKey={selectedItem ? selectedItem.key : undefined}
onChange={this._onChange}
/>
<TextField
name="textTest"
label={"Test"}
/>
</div>
);
}
private _onChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
this.setState({ selectedItem: item });
let opValue = item.text;
console.log(event);
console.log(opValue);
};
}
After inserting Muhammad's logic, here is the error I am getting. Do I need to add an onChange event for the TextField? and then put "this.state.selectedItem" in the handleChange event? Do I need to make a new child component and have the TextField rollup to ParentComponent?
You just need to assign that state in the value prop for the textField as you have the selectedItem in your state
<TextFieid
label={"Test"}
styles={{ root: { width: 300 } }}
value={this.state.selectedItem}
/>
import * as React from "react";
import ChildComponent from './Operations/ChildComponent';
import { DropdownMenuItemType, IDropdownOption } from 'office-ui-fabric-react/lib/Dropdown';
import { TextField} from 'office-ui-fabric-react/lib/TextField';
export interface ParentComponentState {
selectedItem?: { key: string | number | undefined };
value?;
}
export default class ParentComponent extends React.Component{
constructor(props) {
super(props);
this.state = {
value: '',
};
}
public state: ParentComponentState = {
selectedItem: undefined,
};
handleChange = (event) => {
this.setState({
value: event.target.value,
})
};
render(){
const { selectedItem } = this.state;
const options: IDropdownOption[] = [
{ key: 'blank', text: '' },
{ key: 'topLevelMake', text: 'Parents', itemType: DropdownMenuItemType.Header },
{ key: 'topLevel', text: 'TOP LEVEL' },
{ key: 'make', text: 'MAKE ITEM' },
{ key: 'divider_1', text: '-', itemType: DropdownMenuItemType.Divider },
{ key: 'Purchased', text: 'Purchases', itemType: DropdownMenuItemType.Header },
{ key: 'rawMaterial', text: 'RAW MATERIAL' },
{ key: 'buyItem', text: 'BUY ITEM' },
];
return(
<div>
<ChildComponent
options={options}
selectedKey={selectedItem ? selectedItem.key : undefined}
onChange={this._onChange}
/>
<TextField
name="textTest"
label={"Test"}
onChange={this.handleChange}
value={this.state.value}
/>
</div>
);
}
private _onChange = (event: React.FormEvent<HTMLDivElement>, item: IDropdownOption): void => {
this.setState({ selectedItem: item });
this.setState({value: item.text})
let opValue = item.text;
console.log(event);
console.log(opValue);
};
}

Resources