reset On Resolve the course to loop in React - reactjs

I'm trying to reset the Values on change of the Dependency value to the SelectInput. But it course to loop and break the page. Here find the code I have done so far.
How can omit this on my code.
import {
SelectInput,
required
} from 'react-admin';
import data from '../data';
import { withStyles } from '#material-ui/core/styles';
import React, { Component } from 'react';
import { DependentInput } from 'aor-dependent-input';
const initialState = {
way_of_join: data.way_of_join
};
class WayOfJoinSelectInput extends Component {
constructor(props) {
super(props)
this.state = initialState;
}
reset(){
this.setState({initialState});
}
switchSector = (props) => {
if (props !== undefined && Object.keys(props).length > 0) {
var value = props.General_Service.service_sector;
this.reset();
switch (value) {
case 'sleas':
this.state.way_of_join.splice(4, 3)
break;
case 'sltes':
this.state.way_of_join.splice(2, 1)
break;
}
}
};
render() {
return (
<DependentInput resolve={this.switchSector}>
<SelectInput
source="General_Service.way_join"
label="Way of Join"
validate={required()}
// onChange={this.reset()}
choices={this.state.way_of_join}
/>
</DependentInput>
)
}
}
export default withStyles(styles)(WayOfJoinSelectInput);
Here find what getting on error.

import {
SelectInput,
required
} from 'react-admin';
import data from '../data';
import { withStyles } from '#material-ui/core/styles';
import React, { Component } from 'react';
import { DependentInput } from 'aor-dependent-input';
const initialState = {
way_of_join: data.way_of_join
};
class WayOfJoinSelectInput extends Component {
constructor(props) {
super(props)
this.state = initialState;
this.reset=this.reset.bind(this);
}
reset(){
this.setState({initialState});
}
switchSector = (props) => {
if (props !== undefined && Object.keys(props).length > 0) {
var value = props.General_Service.service_sector;
this.reset();
switch (value) {
case 'sleas':
this.state.way_of_join.splice(4, 3)
break;
case 'sltes':
this.state.way_of_join.splice(2, 1)
break;
}
}
};
render() {
return (
<DependentInput resolve={this.switchSector}>
<SelectInput
source="General_Service.way_join"
label="Way of Join"
validate={required()}
onChange={this.reset}
choices={this.state.way_of_join}
/>
</DependentInput>
)
}
}
export default withStyles(styles)(WayOfJoinSelectInput);
You need to bind the functions in constructor or use arrow functions.

Related

React with typescript ==>No overload matches this call

I am getting below error in the screeshot error_2
Here AgGridReact is imported from the ag-grid-react library which i have imported at the top of my code .So i want ask to how can I declare interface to the AgGridReact because it not the component .If it will be normal component then It will be easy to just declare the interface and declare the props inside it
Below is my code
import React, { Component } from 'react';
import { AgGridColumn, AgGridReact } from 'ag-grid-react';
import './Grid.scss';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-alpine.css';
type MyProps = {
className:any
rowData:any
columns:any
updateRecord:any
onDeleteRecord:any
noHoverEffect:any
gridOptions:any
onRowEditingStopped:any
};
type MyState = {
};
export default class Grid extends Component<MyProps, MyState> {
constructor(props:MyProps) {
super(props);
this.state = {};
}
onCellClicked = (params:any) =>
{
// Handle click event for action cells
if (params.column.colId === "Action" && params.event.target.dataset.action)
{
let action = params.event.target.dataset.action;
if (action === "update")
{
this.props.updateRecord(params.node.data.id, params.node.data.name, params.node.data.description, params.node.data.created, params.node.data.created_By);
}
if (action === "delete") {
this.props.onDeleteRecord(params.node.data)
}
}
}
render() {
const gridOptions = {
getRowStyle: (params:any) => {
if (params.node.rowIndex % 2 === 1) {
return { background: '#ebebeb73' };
}
},
};
return (
<div className={["sct-grid", this.props.className, this.props.noHoverEffect && "nohover"].filter(Boolean).join(" ")}>
<AgGridReact gridOptions={gridOptions}
alignedGrid="true"
suppressDragLeaveHidesColumns={true}
pagination={true}
paginationPageSize={7}
rowData={this.getitems()}
onRowEditingStopped={this.onRowEditingStopped}
onRowEditingStarted={this.onRowEditingStarted}
onCellClicked={this.onCellClicked}
editType="fullRow"
suppressClickEdit={true}
enableRangeSelection={true}
columnDefs={this.props.columns}
>
{/* { this.getColumns()}*/}
</AgGridReact>
</div>
);
}
getitems() {
return this.props.rowData;
}
getColumns() {
var listOfColumns :any = [];
if (this.props.columns) {
this.props.columns.forEach((column:any) => {
listOfColumns.push(<AgGridColumn key={column} minWidth="80" maxWidth="120" field={column.field} sortable={column.sortable} filter={column.filter}></AgGridColumn>);
});
}
return listOfColumns;
};
};
Following the documentation, you either need to add getRowStyle property to the AgGridReact component, and/or always return styles from getRowStyle function in gridOptions. Because right now, if your condition if (params.node.rowIndex % 2 === 1) returns false, getRowStyle function is going to return undefined(which AgGridReact apparently doesn't like if looking at the error message).

× Maximum update depth exceeded

Maximum update depth exceeded. This can happen when a component
repeatedly calls setState inside componentWillUpdate or
componentDidUpdate. React limits the number of nested updates to
prevent infinite loops.
this is bossinfo.js
import React from 'react';
import { NavBar, InputItem, TextareaItem, Button } from 'antd-mobile';
import {connect} from 'react-redux';
import {Redirect} from 'react-router-dom';
import AvatarSelector from '../../component/avatar-selector/avatar-selector';
import {updata} from '../../redux/user.redux';
#connect(
state=>state.user,
{updata}
)
class BossInfo extends React.Component{
constructor(props){
super(props)
this.state={
title:'',
company:'',
money:'',
desc:'',
}
}
onChange(key,v){
this.setState({
[key]:v
})
}
render(){
return (
<div>
{this.props.redirectTo?<Redirect to={this.props.redirectTo}></Redirect>:null}
<NavBar mode="dark">Boss完善信息页面</NavBar>
<AvatarSelector selectAvatar={(imagename)=>{
this.setState({
avatar:imagename
})
}}></AvatarSelector>
<InputItem onChange={(v)=>{this.onChange('title',v)}}>
招聘职位
</InputItem>
<InputItem onChange={(v)=>{this.onChange('company',v)}}>
公司名称
</InputItem>
<InputItem onChange={(v)=>{this.onChange('money',v)}}>
职位薪资
</InputItem>
<TextareaItem
title='职位要求'
rows={3}
autoHeight
onChange={(v)=>{this.onChange('desc',v)}}
>
</TextareaItem>
<Button onClick={()=>this.props.updata(this.state)} type='primary'>保存</Button>
</div>
)
}
}
export default BossInfo;
this is user.redux.js
import axios from "axios";
import { getRedirectPath } from '../util' ;
const AUTH_SUCCESS = 'AUTH_SUCCESS';
const ERROR_MSG = 'ERROR_MSG';
const LOAD_DATA = 'LOAD_DATA';
const initStatus={
redirectTo:'',
msg:'',
user:'',
type:'',
}
//reducer
export function user(state=initStatus,action){
switch(action.type){
case AUTH_SUCCESS:
return {...state,msg:'',redirectTo:getRedirectPath(action.data),...action.data}
case LOAD_DATA:
return {...state,...action.data}
case ERROR_MSG:
return {...state,isAuth:false,msg:action.msg}
default:
return state;
}
}
//action
function authSuccess(data){
return { type:AUTH_SUCCESS, data:data }
}
function errorMsg(msg){
return { type:ERROR_MSG, msg:msg }
}
export function register({user,pwd,repeatpwd,type}){
if(!user || !pwd){
return errorMsg('用户名密码必须输入!')
}
if(pwd!=repeatpwd){
return errorMsg('两次密码输入不一致!')
}
//redux-thunk支持返回函数的写法(这边是异步)
return dispatch =>{
axios.post('/user/register',{user,pwd,type}).then(res=>{
if(res.status==200&&res.data.code==0){
dispatch(authSuccess({user,pwd,type,_id:res.data.data._id}))
}else{
dispatch(errorMsg(res.data.msg))
}
})
}
}
export function login({user,pwd}){
if(!user || !pwd){
return errorMsg('用户名和密码不能为空!')
}
return dispatch =>{
axios.post('/user/login',{user,pwd}).then(res=>{
if(res.status==200 && res.data.code==0){
dispatch(authSuccess(res.data.data))
}else{
dispatch(errorMsg(res.data.msg))
}
})
}
}
export function loadData(userinfo){
return {type:LOAD_DATA,data:userinfo}
}
export function updata(data){
return dispatch=>{
axios.post('/user/updata',data)
.then(res=>{
if(res.status==200 && res.data.code==0){
dispatch(authSuccess(res.data.data))
}else{
dispatch(errorMsg(res.data.msg))
}
})
}
}
Why do you keep reporting this problem?Is this pointing in the wrong direction?Asking for help
The onChange function is executing on each render change the function to arrow function like
onChange=(key,v)=>{
v.stopPropagation();
this.setState({
[key]:v
})
}

React and table does not sync

I'm using react antd table with pagination,sort & etc. it'll fetch data when component is loaded. when te user clicks on pagination it should call Api and get new data accordingly. it's getting bada but the table won't update with new data.
I'm new with react. please help me with this,
import PropTypes from 'prop-types';
import React, { Component } from "react";
import { connect } from "react-redux";
import { bindActionCreators } from 'redux';
import { Row, Col } from "antd";
import clone from "clone";
import Button from "../../components/uielements/button";
import PageHeader from "../../components/utility/pageHeader";
import Box from "../../components/utility/box";
import LayoutWrapper from "../../components/utility/layoutWrapper";
import SignUpForm from "../../components/vendorSignup";
import basicStyle from "../../settings/basicStyle";
import actions from "../../redux/vendorSignUp/actions";
import { createColumns } from "./config";
import { ButtonWrapper } from "../../components/card/cardModal.style";
import SimpleTable from "./antTables/tableViews/sortView";
import ContentHolder from '../../components/utility/contentHolder';
import Spin from '../Feedback/Spin/spin.style';
const { addVendor, getVendors } = actions;
class Cards extends Component {
static propTypes = {
dispatch: PropTypes.func
};
constructor(props) {
super(props);
this.addColumn = this.addColumn.bind(this);
this.editColumn = this.editColumn.bind(this);
this.handleCancel = this.handleCancel.bind(this);
this.submitCard = this.submitCard.bind(this);
this.updateCard = this.updateCard.bind(this);
this.tableInfo = {
title: "Sort Table",
value: "sortView",
columns: []
};
this.tableInfo.columns = createColumns(this.editColumn);
this.state = {
editView: false,
selectedCard: null,
modalType: ""
};
}
componentWillMount() {
const { getVendors } = this.props.actions;
}
render() {
const style = {
textAlign: 'center',
background: '#f1f3f6',
padding: '30px 50px'
};
const { rowStyle, colStyle, gutter } = basicStyle;
const { editView, selectedCard, modalType } = this.state;
const vendorSignUp = clone(this.props.vendorSignUp);
if (vendorSignUp.length == 0) {
return (<LayoutWrapper>
<PageHeader>Vendors</PageHeader>
<ContentHolder>
<div style={style}>
<Spin spinning={vendorSignUp.length === 0} />
</div>
</ContentHolder>
</LayoutWrapper>);
}
return (
<LayoutWrapper>
<PageHeader>Vendors</PageHeader>
<Row style={rowStyle} gutter={gutter} justify="start">
<Col md={24} sm={24} xs={24} style={colStyle}>
<Box>
<ButtonWrapper className="isoButtonWrapper">
<Button type="primary" className="" onClick={this.addColumn}>
Add New Vendor
</Button>
</ButtonWrapper>
<SimpleTable columns={this.tableInfo.columns} dataSource={vendorSignUp} loading={this.loading} onChange={this.onChange} />
{selectedCard ? (
<SignUpForm
saveFormRef={this.saveFormRef}
editView={editView}
modalType={modalType}
onCancel={this.handleCancel}
onCreate={this.submitCard}
onOk={this.submitCard}
wrappedComponentRef={this.saveFormRef}
/>
) : ("")}
</Box>
</Col>
</Row>
</LayoutWrapper>
);
}
}
function mapStateToProps(state) {
return {
...state.vendorSignUp.toJS()
};
}
function mapDispatchToProps(dispatch) {
return {
actions: bindActionCreators({
getVendors, addVendor
}, dispatch)
}
}
export default connect(mapStateToProps, mapDispatchToProps)(Cards);
Here is my table view;
import React, { Component } from 'react';
import { connect } from 'react-redux';
import TableWrapper from '../antTable.style';
import actions from "../../../../redux/vendorSignUp/actions";
const { getVendors } = actions;
class SignIn extends Component {
constructor(props) {
super(props);
this.onChange = this.onChange.bind(this);
this.state = {
dataList: this.props.dataSource || this.props.dataList.getAll()
};
this.columns = this.props.columns || this.props.tableInfo.columns;
}
onChange(pagination, filters, sorter) {
if (sorter.order) {
if (sorter.order == "ascend") {
const { getVendors } = this.props;
this.setState({
loading: true,
});
getVendors('3-5');
}
else {
this.props.dataSource.sort(function (a, b) {
var x = a[sorter.field].toLowerCase();
var y = b[sorter.field].toLowerCase();
if (y < x) { return -1; }
if (y > x) { return 1; }
return 0;
});
}
}
}
render() {
return (
<TableWrapper
columns={this.columns}
onChange={this.onChange}
dataSource={this.state.dataList}
className="isoSortingTable"
pagination={{ pageSize: 10 }}
loading={this.state.loading}
/>
);
}
}
function mapStateToProps(state) {
return {
...state
};
}
export default connect(mapStateToProps,
{ getVendors }
)(SignIn);
problem was in the constructor.it's will be executed only one time. therefore this.state.datalist will be the same. that's why it did not work.

trying to pass my arrays (props) into my publish function as selector

import { Mongo } from 'meteor/mongo';
import { Meteor } from 'meteor/meteor';
import React, {Component} from 'react';
import {check} from 'meteor/check';
export const Adressen = new Mongo.Collection('Phonebook');
if (Meteor.isServer) {
Meteor.publish('ArrayToExport', function(branches) {
check(branches, [Match.Any]);
if(branches.length > 10){
return this.ready()
};
return Adressen.find(
{branche: {$in: branches}}, {fields: {firmenname:1, plz:1}}
);
});
}
.
import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import {Adressen} from "../api/MongoDB";
class ExportArray extends Component{
constructor(props){
super(props);
this.state = {
branches: this.props.filteredBranches
};
}
render(){
return(
<div>
<button onClick={this.exportArrays}></button>+
</div>
);
}
}
export default withTracker( (branches) => {
Meteor.subscribe('ArrayToExport', branches);
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
this.props.filteredBranche is a pure array,generated through controlled input field. this.props.filteredBranches changes as Input changes, in parent Component.
I thought I was sending my this.props.filteredBranches as an argument through withTracker function. But nothing is passed to the publish function.
if (Meteor.isServer) {
arrayExfct = function (array){
return {
find: {branche:{$in: array }},
fields: {firmenname:1, plz:1}
};
}
Meteor.publish('ArrayToExport', function (array) {
return Adressen.find(
arrayExfct(array).find, arrayExfct(array).fields);
});
}
.
export default withTracker( () => {
arrayExfct = function(array) {
return {
find: {branche: {$in: array}},
fields: {firmenname:1, plz:1}
}
}
var array = ['10555'];
Meteor.subscribe('ArrayToExport', array );
var arrayExfct = Adressen.find(arrayExfct(array).find, arrayExfct(array).fields);
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
It would help if you also added an example of where you used this component and how you pass props to it, but I think I see your problem.
You expect the local state in your rendering component to get into the withTracker container, but that would be the other way around. When you make the withTracker container, you are really making another react component that renders your display component (ExportArray) and passes the data (ArrayToExport) down into it.
So, props go like this currently:
external render -> withTracker component -> ExportArray
What you need to do it to get the filteredBranches (which you pass from a parent component?) from the props argument in withTracker and pass that to the subscribtion,
class ExportArray extends Component{
exportArrays () {
const { ArrayToExport } = this.props;
}
render(){
const { ArrayToExport } = this.props;
return(
<div>
<button onClick={this.exportArrays}></button>+
</div>
);
}
}
export default withTracker(propsFromParent => {
const { filteredBranches } = propsFromParent;
Meteor.subscribe('ArrayToExport', filteredBranches);
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
Hi the issue is with the code below. The parameter called branches is the props so branches.branches is the array you passed in.
export default withTracker( (branches) => {
Meteor.subscribe('ArrayToExport', branches);
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
Try the following.
export default withTracker( ({branches}) => {
Meteor.subscribe('ArrayToExport', branches);
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
Notice all that changed was
(branches)
became
({branches})
I solved my problem with a combination of Session Variables and State.
//Client
import React, { Component } from 'react';
import { withTracker } from 'meteor/react-meteor-data';
import {Adressen} from "../api/MongoDB";
import {Meteor} from 'meteor/meteor';
import { Session } from 'meteor/session';
class ExportArray extends Component{
constructor(){
super();
this.state = {
x: [],
y: []
};
this.exportArrays = this.exportArrays.bind(this);
}
exportArrays(e){
e.preventDefault();
this.setState({x: this.props.filteredBranches});
this.setState({y: this.props.filteredPostleitzahlen});
}
render(){
var selector = {branche: {$in: this.state.x},plz: {$in: this.state.y}};
Session.set('selector', selector);
return(
<div>
<button onClick={this.exportArrays}> Commit </button>
</div>
);
}
}
export default withTracker( () => {
const ArrayfürExport = Meteor.subscribe('ArrayToExport', Session.get('selector') );
return {
ArrayToExport: Adressen.find({}).fetch()
};
})(ExportArray);
//Server
Meteor.publish('ArrayToExport', function (selector) {
console.log('von mongodb', selector);
return Adressen.find(
selector
, {
fields: {firmenname:1, plz:1}
});
});
}

Meteor - return inside of a Tracker.autorun function not returning anything

The function renderNotes() is supposed to return the mapped array which is in a separate file. I noticed that when I return some JSX nothing returns to the screen. I think I know the reason why is because it is returning the info to the tracker function. How would I get the info to return to the renderNotes() function while inside the tracker.autorun() function?
import { Meteor } from "meteor/meteor";
import React from "react";
import { withRouter, Link } from "react-router-dom";
import { Accounts } from "meteor/accounts-base";
import { Tracker } from "meteor/tracker";
import SubjectRoutes from "./subjectRoutes/subjectRoutes";
import { Notes } from "../methods/methods"
import Menu from "./Menu.js";
class Home extends React.Component{
componentWillMount() {
if(!Meteor.userId()){
this.props.history.replace("/login")
}
}
logoutUser(e){
e.preventDefault()
Accounts.logout(() => {
this.props.history.push("/login");
});
}
renderNotes(){
Tracker.autorun(function () {
Meteor.subscribe('notes');
let notes = Notes.find().fetch();
// return notes.map((note) => {
// return <p>{note.imageURL}</p>
// })
return <p>asdas</p> //<--Here
});
}
render(){
return (
<div>
<button onClick={this.logoutUser.bind(this)}>Logout</button>
{this.renderNotes()}
<Menu />
</div>
)
}
}
export default withRouter(Home);
Don't know whether this is a proper answer but I like to usually do something like this
import TrackerReact from 'meteor/ultimatejs:tracker-react';
import { Notes } from "../methods/methods";
export default class Home extends TrackerReact(React.Component) {
constructor(props,) {
super(props);
this.state = {
subscription:{
publishNotes: Meteor.subscribe("publish-Notes")
}
};
}
returnNotes(){
return Notes.find().fetch();
}
render(){
...
const stuff = this.returnNotes().map((note)=>{
return <p>{note}</p>
});
return (
....
{stuff}
)
}
}
This worked for me:
import { Meteor } from "meteor/meteor";
import React from "react";
import { withRouter, Link } from "react-router-dom";
import { Accounts } from "meteor/accounts-base";
import { Tracker } from "meteor/tracker";
import SubjectRoutes from "./subjectRoutes/subjectRoutes";
import { Notes } from "../methods/methods"
import Menu from "./Menu.js";
class Home extends React.Component{
constructor(props){
super(props)
this.state = {
notes: []
}
}
componentWillMount() {
if(!Meteor.userId()){
this.props.history.replace("/login")
}
this.tracker = Tracker.autorun(()=>{
Meteor.subscribe('notes');
let notes = Notes.find().fetch();
this.setState({ notes })
});
}
componentWillUnmount() {
this.tracker.stop();
}
logoutUser(e){
e.preventDefault()
Accounts.logout(() => {
this.props.history.push("/login");
});
}
renderNotes(notes){
return notes.map((note) => {
return (
<div key={note._id}>
<img src={note.imageURL} />
<p>{note.type}</p>
</div>
)
});
}
render(){
return (
<div>
<button onClick={this.logoutUser.bind(this)}>Logout</button>
<Menu />
{this.renderNotes(this.state.notes)}
</div>
)
}
}
export default withRouter(Home);

Resources