I'm using Material-UI components to build my website. I have a header component with a search field which uses mui InputBase under the hood. When user enters empty input (that is they don't enter anything and just click enter) I want to display a mui Snackbar which will warn the user the no meaningful input was entered.
I can't get the combination of the two components to work together. In addition because search field state doesn't really change when user enters nothing it doesn't reload so if user repeatedly presses Enter the snackbar won't appear. I use this.forceUpdate(); but is there a more elegant way to implement such logic?
This is my code:
for the search input field:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import InputBase from '#material-ui/core/InputBase';
import { withStyles } from '#material-ui/core/styles';
import { withRouter } from 'react-router-dom';
import { connect } from 'react-redux';
import { getAppInfo } from '../../actions/appActions.js';
import constants from '../../constants.js';
import { AppSearchBarInputStyles } from '../styles/Material-UI/muiStyles.js';
import AppNotFound from './AppNotFound.js';
class AppSearchBarInput extends Component {
state = {
appId: ''
}
onChange = e => {
this.setState({ appId: e.target.value });
}
onKeyDown = e => {
const { appId } = this.state;
if (e.keyCode === constants.ENTER_KEY && appId !== '') {
this.props.getAppInfo({ appId });
this.setState({
appId: ''
});
}
this.props.history.push('/app/appInfo');
this.forceUpdate();
}
render() {
const { classes } = this.props;
const { appId } = this.state;
console.log(`appId from AppSearchInput=${appId === ''}`);
return (
<div>
<InputBase
placeholder="Search…"
classes={{
root: classes.inputRoot,
input: classes.inputInput,
}}
onChange={this.onChange}
onKeyDown={this.onKeyDown}
value={this.state.appId} />
{ appId === '' ? <AppNotFound message={constants.MESSAGES.APP_BLANK()}/> : ''}
</div>
)
}
}
AppSearchBarInput.propTypes = {
classes: PropTypes.object.isRequired
}
const AppSearchBarWithStyles = withStyles(AppSearchBarInputStyles)(AppSearchBarInput);
const AppSearchBarWithStylesWithRouter = withRouter(AppSearchBarWithStyles);
export default connect(null, { getAppInfo })(AppSearchBarWithStylesWithRouter);
for the snackbar:
import React from 'react';
import Snackbar from '#material-ui/core/Snackbar';
import constants from '../../constants.js';
import SnackbarMessage from './SnackbarMessage.js';
class AppNotFound extends React.Component {
state = {
open: true,
};
handleClose = event => {
this.setState({ open: false });
};
render() {
const { message } = this.props;
return (
<Snackbar
anchorOrigin={{
vertical: 'top',
horizontal: 'center',
}}
open={this.state.open}
autoHideDuration={6000}
onClose={this.handleClose}
>
<SnackbarMessage
onClose={this.handleClose}
variant="warning"
message={message}
/>
</Snackbar>
);
}
}
export default AppNotFound;
I think the good way to achieve what You want is by adding another state property called snackBarOpen which will help You to determine if user has entered empty value or something meaningful:
AppSearchBarInput Component
state = {
appId: '',
snackBarOpen: false
}
handleKeyDown = (e) => {
if (e.keyCode === 13 && e.target.value === '') {
this.setState({
appId: e.target.value,
snackBarOpen: true
});
} else {
this.setState({
appId: e.target.value
})
}
}
handleCloseSnackBar = () => {
this.setState({
snackBarOpen: false
});
}
And then just render also <AppNotFound /> in render() method(it will be hidden by default because it will depend on open prop):
render() {
const { snackBarOpen } = this.state;
return(
<div>
/* <InputBase /> here */
<AppNotFound message={/* Your message here */} open={snackBarOpen} onClose={this.handleCloseSnackBar} />
</div>
)
}
AppNotFound Component
You can remove all methods now and leave only render() one which will look next:
render() {
const { message, open, onClose } = this.props;
return (
<Snackbar
// ...
open={open}
// ...
onClose={onClose}
>
<SnackbarMessage
onClose={onClose}
// ...
message={message}
/>
</Snackbar>
);
}
Hope that my answer will be useful :)
Related
There is a field where the user must introduce a text. If the text is the desired one, a button should change its color so the user knows the text is the correct one.
So far I've done the validation of the text, an error message is shown if the text is not the desired one but I don't know how to connect this to the button's styling.
Here is my code:
import React from 'react';
import { Redirect } from 'react-router-dom';
import { connect } from 'react-redux';
import * as Yup from 'yup';
import { Formik, Form, Field } from 'formik';
import { Button, Modal, Input } from 'semantic-ui-react';
import { Creators } from '../../../actions';
import './FridgeForm.scss';
class CreateFridgeForm extends React.Component {
constructor(props) {
super(props);
this.state = {
open: false,
redirectCreate: false,
};
}
componentDidMount() {
const { edit, getFridge, fridge, getFridges } = this.props;
if (edit) {
getFridge(fridge._id);
getFridges();
}
}
onOpen = () => {
this.setState({ open: true });
};
closeModal = () => {
this.setState({ open: false });
};
handleDelete = values => {
const { deleteFridge, fridge, getFridges } = this.props;
deleteFridge(fridge._id);
this.setState({ open: false });
this.setState({ redirectCreate: true });
getFridges();
};
render() {
const { trigger } = this.props;
const title = 'Do you want to delete a fridge?';
const { open, redirectCreate } = this.state;
if (redirectCreate) {
return <Redirect to="/fridges" />;
}
const initialValues = {
deleteText: '',
};
const wrongTextMessage =
'You must write DELETE in order to delete the fridge';
const requiredErrorMessage = 'This field is required';
const deleteTextValidation = /DELETE\b/g;
const validationSchema = Yup.object({
deleteText: Yup.string()
.matches(deleteTextValidation, wrongTextMessage)
.required(requiredErrorMessage),
});
return (
<Modal
open={open}
trigger={trigger}
onOpen={this.onOpen}
onClose={this.closeModal}
size="small">
<Modal.Header >{title}</Modal.Header>
<Modal.Content >
<Modal.Description >
Are you sure you want to delete?
</Modal.Description>
<Formik
initialValues={initialValues}
validationSchema={validationSchema}
onSubmit={values => this.handleDelete(values)}>
{({ values, errors, touched, setFieldValue }) => (
<Form>
<Field
className="add-fridge-input"
name="deleteText"
as={Input}
placeholder="Write DELETE"
/>
<div className="add-fridge-error">
{touched.deleteText && errors.deleteText
? errors.deleteText
: null}
</div>
<Button className="delete-modal-button" type="submit"> // here is the button
Confirm
</Button>
</Form>
)}
</Formik>
</Modal.Content>
</Modal>
);
}
}
const mapStateToProps = state => ({
fridges: state.fridges.fridges,
fridge: state.fridges.selectedFridge,
});
const mapDispatchToProps = {
getFridges: Creators.getFridgesRequest,
getFridge: Creators.getFridgeRequest,
deleteFridge: Creators.deleteFridgeRequest,
};
export default connect(mapStateToProps, mapDispatchToProps)(CreateFridgeForm);
Is there a way to notify the button if validationSchema validates as correct the text?
While building a react application I want to enable a feature in the application to allow the user to add a new value in the drop-down. Is it possible to add this feature in the application?
Adding the following example
import React from "react";
import { MDBDropdown, MDBDropdownToggle, MDBDropdownMenu, MDBDropdownItem } from "mdbreact";
const DropdownPage = () => {
return (
<MDBDropdown>
<MDBDropdownToggle caret color="primary">
MDBDropdown
</MDBDropdownToggle>
<MDBDropdownMenu basic>
<MDBDropdownItem>Action</MDBDropdownItem>
<MDBDropdownItem>Another Action</MDBDropdownItem>
<MDBDropdownItem>Something else here</MDBDropdownItem>
<MDBDropdownItem divider />
<MDBDropdownItem>Separated link</MDBDropdownItem>
</MDBDropdownMenu>
</MDBDropdown>
);
}
export default DropdownPage;
After the divider can we add a '+' symbol and if the user clicks on it then he can type in a new value and that gets added to the existing dropdown. Can anyone please help with the following.
Regards
import React from 'react';
import { MDBDropdown, MDBDropdownToggle, MDBDropdownMenu, MDBDropdownItem } from "mdbreact";
export default class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
isDrop: false,
isNewItem: false,
items: ['Action', 'Another Action', 'Something else here'],
newItem: ''
}
}
render (){
return (
<MDBDropdown>
<MDBDropdownToggle caret color="primary">
MDBDropdown
</MDBDropdownToggle>
<MDBDropdownMenu>
{
this.state.items.map((item, index) => {
return(
<MDBDropdownItem key={index}>{item}</MDBDropdownItem>
)
})
}
<MDBDropdownItem divider />
<MDBDropdownItem>Separated link</MDBDropdownItem>
<MDBDropdownItem toggle={false} onClick={this.updateIsNewItem}>{this.state.isNewItem ? 'x' : '+'}</MDBDropdownItem>
{
this.state.isNewItem &&
<MDBDropdownItem toggle={false}>
<input name='newItem' type='text' onChange={this.handleChange} value={this.state.newItem}/>
<button onClick={this.addNewItem}>Add</button>
</MDBDropdownItem>
}
</MDBDropdownMenu>
</MDBDropdown>
)
}
addNewItem = () => {
if(this.state.newItem !== ''){
this.setState({
items: [...this.state.items, this.state.newItem],
newItem: '',
isNewItem: false
});
}
}
handleChange = (event) => {
const name = event.target.name;
const value = event.target.value;
this.setState({[name]: value});
}
updateIsNewItem = () => {
this.setState(prevState => ({isNewItem: !prevState.isNewItem}));
}
}
I want to hide some component based on some flag in react js.
I have an App component where I have Login and other components, I want to hide the other component until Login components this.state.success is false and on click of a button I am changing the sate, but it's not working, I am new to react,
My App Class compoenent -
import React, { Component } from "react";
import logo from "../../logo.svg";
// import Game from "../Game/Game";
import Table from "../Table/Table";
import Form from "../Table/Form";
import Clock from "../Clock/Clock";
import "./App.css";
import Login from "../Login/Login";
class App extends Component {
state = {
success: false
};
removeCharacter = index => {
const { characters } = this.state;
this.setState({
characters: characters.filter((character, i) => {
return i !== index;
})
});
};
handleSubmit = character => {
this.setState({ characters: [...this.state.characters, character] });
};
handleSuccess() {
this.setState({ success: true });
}
render() {
const { characters, success } = this.state;
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<span className="Span-inline">App</span>
<Clock time={new Date()} />
</header>
<Login success={success} handleSuccess={this.handleSuccess} />
{success && (
<div className="container">
<h1>React Tutorial</h1>
<p>Add a character with a name and a job to the table.</p>
<Table
characterData={characters}
removeCharacter={this.removeCharacter}
/>
<h3>Add New character</h3>
<Form handleSubmit={this.handleSubmit} />
</div>
)}
{/* <Game /> */}
</div>
);
}
}
export default App;
My Login component -
import React, { Component } from "react";
import Greeting from "./Greeting";
import LogoutButton from "./LogoutButton";
import LoginButton from "./LoginButton";
class Login extends Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {
isLoggedIn: false,
name: "",
success: false
};
}
handleLoginClick() {
this.setState({ isLoggedIn: true });
this.setState({ success: true });
}
handleLogoutClick() {
this.setState({ isLoggedIn: false });
this.setState({ success: false });
}
onChange = e => {
this.setState({
name: e.target.value
});
};
render() {
const isLoggedIn = this.state.isLoggedIn;
const name = this.state.name;
// const successLogin = this.state.success;
let button;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting
isLoggedIn={isLoggedIn}
name={name}
onChange={this.onChange}
/>
{button}
</div>
);
}
}
export default Login;
please guide me on what I am doing wrong.
Why sometime debuggers do not trigger in react component?
For the sake of example I have used functional stateless component here. You can use Class component all upto you.
const conditionalComponent = (props) => {
let condition = true;
return (
{condition && <div><h1>Hello world</h1></div>}
}
Instead of directly giving condition you can even call function which returns a boolean value.
handleLoginClick() {
this.setState({ isLoggedIn: true });
this.setState({ success: true });
this.props.handleSuccess()
}
do like this
<Login success={success} handleSuccess=
{this.handleSuccess} />
bind this function
We have created a notification system that uses the material ui Snackbar with an action button and close button. I'm trying to add a listener event for enter so that specific notification's action will fire and close the Snackbar. I attempted to do this when the component is mounted, but the components mount when the application loads they are just not shown until their state is set to open. This resulted in all the actions attached to the Snackbars firing at once. I then attempted to use a ref but had no success. Below I will show the code for the button that calls the notifications and the notification component itself. I'm looking for suggestions on how to close the active Snackbar and fire off its action with enter without activating the other mounted notifications.
UPDATE: I changed the key from enter to spacebar and it works as desired. It seems the issue lies with the enter key itself.
https://material-ui.com/api/root-ref/#__next
import React from 'react';
import { connect } from 'react-redux';
import { withStyles } from '#material-ui/core/styles';
import IconButton from '#material-ui/core/IconButton';
import DeleteIcon from '#material-ui/icons/Delete';
import Tooltip from '#material-ui/core/Tooltip';
import { NotifierConfirm, enqueueInfo } from '#paragon/notification-tools';
import { deleteDocument } from '../../actions/documents';
import { getSelectedDocument } from '../../selectors/documents';
import { jobIsLocked } from '../../modules/jobLocking'; // eslint-disable-line
const styles = ({
border: {
borderRadius: 0,
},
});
class DeleteDocument extends React.Component {
state = {
deleteDocumentOpen: false,
}
onDeleteFile = () => {
if (jobIsLocked()) {
return;
}
this.setState({ deleteDocumentOpen: true });
}
closeDeleteDocument = () => {
this.setState({ deleteDocumentOpen: false });
};
onConfirmDelete = () => {
this.props.onDeleteFile(this.props.selectedDocument.id);
this.setState({ deleteDocumentOpen: false });
}
render() {
const { classes } = this.props;
return (
<div>
<Tooltip disableFocusListener id="delete-tooltip" title="Delete Document">
<div>
<IconButton
className={`${classes.border} deleteDocumentButton`}
disabled={(this.props.selectedDocument == null)}
onClick={this.onDeleteFile}
>
<DeleteIcon />
</IconButton>
</div>
</Tooltip>
<NotifierConfirm
open={this.state.deleteDocumentOpen}
onClose={this.closeDeleteDocument}
onClick={this.onConfirmDelete}
message="Are you sure you want to DELETE this document?"
buttonText="Delete"
/>
</div>
);
}
}
const mapStateToProps = (state) => {
const selectedDocument = getSelectedDocument(state);
return {
selectedDocument,
};
};
function mapDispatchToProps(dispatch) {
return {
onDeleteFile: (documentId) => {
dispatch(deleteDocument(documentId));
},
enqueueInfo,
};
}
export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(DeleteDocument));
import React from 'react';
import { withStyles, WithStyles, StyleRulesCallback } from '#material-ui/core/styles';
import Button from '#material-ui/core/Button';
import Snackbar from '#material-ui/core/Snackbar';
import IconButton from '#material-ui/core/IconButton';
import CloseIcon from '#material-ui/icons/Close';
import RootRef from '#material-ui/core/RootRef';
interface NotifierConfirmProps {
open: boolean;
onClose: any;
onClick: () => void;
message: string;
messageSecondary?: any;
buttonText: string;
}
type OwnProps = NotifierConfirmProps & WithStyles<typeof styles>;
const styles: StyleRulesCallback = () => ({
snackbar: {
marginTop: 85,
zIndex: 10000000,
'& div:first-child': {
'& div:first-child': {
width: '100%',
},
},
},
close: {
padding: 8,
marginLeft: 8,
},
buttonColor: {
backgroundColor: '#F3D06E',
},
messageDiv: {
width: '100%',
}
});
class NotifierConfirmComponent extends React.Component<OwnProps> {
notifierRef: React.RefObject<{}>;
constructor(props: OwnProps) {
super(props);
// create a ref to store the textInput DOM element
this.notifierRef = React.createRef();
this.focusNotifier = this.focusNotifier.bind(this);
}
keyPressHandler = (event: any) => {
if (!this.props.open) return;
if (event.keyCode === 27) {
this.props.onClose();
}
if (event.keyCode === 13) {
this.props.onClick();
}
}
focusNotifier() {
// Explicitly focus the text input using the raw DOM API
// Note: we're accessing "current" to get the DOM node
// this.notifierRef.current.focus(); this will not work
}
componentDidMount() {
document.addEventListener('keydown', this.keyPressHandler, false);
}
componentWillUnmount() {
document.removeEventListener('keydown', this.keyPressHandler, false);
}
render() {
const { classes } = this.props;
return (
<React.Fragment>
<RootRef rootRef={this.notifierRef}>
<Snackbar
className={classes.snackbar}
anchorOrigin={{
vertical: 'top',
horizontal: 'center',
}}
open={this.props.open}
onClose={this.props.onClose}
ContentProps={{
'aria-describedby': 'message-id',
}}
message={
<div className={classes.messageDiv} id="message-id">
{this.props.message}<br />
{this.props.messageSecondary}
</div>}
action={[
<Button
className={`${classes.buttonColor} confirmActionButton`}
variant="contained"
key={this.props.buttonText}
size="small"
onClick={this.props.onClick}
>
{this.props.buttonText}
</Button>,
<IconButton
key="close"
aria-label="Close"
color="inherit"
className={classes.close}
onClick={this.props.onClose}
>
<CloseIcon />
</IconButton>,
]}
/>
</RootRef>
</React.Fragment>
);
}
}
export const NotifierConfirm = withStyles(styles)(NotifierConfirmComponent);
The answer for this was changing the event listener to keyup instead of
keydown. Deduced this from this post. Why do Enter and Space keys behave differently for buttons?
I have a array and I want to render the this array into a few redux forms. I found out that all the forms are rerendered. the code looks like the following:
Form.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { Link, Events, scrollSpy } from 'react-scroll';
import styles from './Form.css';
import MultipleForm from './MultipleForm';
class Form extends Component {
constructor(props) {
super(props);
const {
workflows,
} = this.props;
this.state = {
curTab: workflows.length > 0 ? workflows[0] : '',
curForm: '',
};
}
componentDidMount() {
Events.scrollEvent.register('begin');
Events.scrollEvent.register('end');
scrollSpy.update();
}
componentWillReceiveProps(nextProps) {
const {
workflows,
} = nextProps;
if (workflows && workflows.length > this.props.workflows) {
this.setState({
curTab: workflows[0],
});
}
}
componentWillUnmount() {
Events.scrollEvent.remove('begin');
Events.scrollEvent.remove('end');
}
handleChangeTab = (value) => {
this.setState({
curTab: value,
});
}
handleActiveTab = (workflow) => {
console.log(workflow);
}
render() {
const {
workflows,
schemaNames,
...rest
} = this.props;
return (
<div className={styles.container}>
<header>
<PerspectiveBar
value={this.state.curTab}
onChange={this.handleChangeTab}
style={{
position: 'fixed',
left: '0',
top: '48px',
width: '100vw',
zIndex: '1380',
}}
>
{workflows.map(wf => (
<PerspectiveTab
key={wf}
label={wf}
value={wf}
onActive={() => this.handleActiveTab(wf)}
/>
))}
</PerspectiveBar>
</header>
<div className={styles.formContainer}>
<Paper className={styles.paperContainer}>
<MultipleForm
workflow={this.state.curTab}
schemaNames={schemaNames}
{...rest}
/>
</Paper>
</div>
<Drawer className={styles.drawer} containerStyle={{ height: 'calc(100% - 104px)', top: '104px' }}>
<div className={styles.drawerContainer}>
{schemaNames.map(schemaName => (
<Link
onSetActive={(to) => {
this.setState({
curForm: to,
});
}}
to={schemaName}
duration={500}
offset={-104}
spy
smooth
>
<MenuItem
checked={this.state.curForm === schemaName}
>
{schemaName}
</MenuItem>
</Link>
))}
</div>
</Drawer>
</div>
);
}
}
Form.propTypes = {
schemaNames: PropTypes.arrayOf(PropTypes.string),
workflows: PropTypes.arrayOf(PropTypes.string),
fetchSchemaNames: PropTypes.func.isRequired,
};
Form.defaultProps = {
schemaNames: [],
workflows: [],
};
export default Form;
MultipleForm.jsx
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import FlatButton from 'material-ui/FlatButton';
import { Element } from 'react-scroll';
import SchemaForm from './SchemaForm';
class MultipleForm extends Component {
componentDidMount() {
console.log('MultipleForm Mounted');
const {
workflow,
fetchSchemaNames,
} = this.props;
if (workflow) fetchSchemaNames(workflow);
}
componentWillReceiveProps(nextProps) {
const {
workflow,
fetchSchemaNames,
} = nextProps;
if (workflow && this.props.workflow !== workflow) fetchSchemaNames(workflow);
}
componentDidUpdate() {
const {
schemaNames,
schemas,
initialValues,
fetchSchemas,
fetchInitialValues,
} = this.props;
const schemasNeedToFetch = this.remainingSchemas(schemaNames, schemas);
if (schemasNeedToFetch.length !== 0) fetchSchemas(schemasNeedToFetch);
const initialValuesNeedToFetch = this.remainingInitialValues(schemaNames, initialValues);
if (initialValuesNeedToFetch.lenght !== 0) fetchInitialValues(initialValuesNeedToFetch, 1);
}
remainingSchemas = (schemaNames, schemas) =>
schemaNames.filter(schemaName => schemaName in schemas === false).sort();
remainingInitialValues = (schemaNames, initialValues) =>
schemaNames.filter(schemaName => schemaName in initialValues === false).sort();
handleSubmitAll = (event) => {
event.preventDefault();
const {
submit,
schemas,
schemaNames,
} = this.props;
schemaNames
.map(schemaName => schemas[schemaName].title)
.forEach((title) => {
submit(title);
});
}
render() {
const {
schemaNames,
schemas,
initialValues,
postForm,
} = this.props;
schemaNames.sort((a, b) => a.localeCompare(b));
return (
<div>
{schemaNames.map(schemaName => (
<Element name={schemaName}>
<SchemaForm
key={schemaName}
schema={schemas[schemaName]}
initialValue={initialValues[schemaName]}
schemaName={schemaName}
postForm={postForm}
/>
</Element>
))}
<div>
<FlatButton
label="Submit"
/>
<FlatButton label="Deploy" />
</div>
</div>);
}
}
MultipleForm.propTypes = {
workflow: PropTypes.string.isRequired,
submit: PropTypes.func.isRequired,
fetchSchemaNames: PropTypes.func.isRequired,
schemas: PropTypes.object,
schemaNames: PropTypes.arrayOf(PropTypes.string),
initialValues: PropTypes.object,
fetchSchemas: PropTypes.func.isRequired,
fetchInitialValues: PropTypes.func.isRequired,
postForm: PropTypes.func.isRequired,
};
MultipleForm.defaultProps = {
schemaNames: [],
};
export default MultipleForm;
SchemaForm
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import Liform from 'liform-react';
import theme from './NokiaTheme';
import styles from './Form.css';
class SchemaForm extends Component {
componentDidMount() {
console.log('schema mounted');
}
shouldComponentUpdate() {
return false;
}
handleSubmit = (value) => {
const {
postForm,
schemaName,
} = this.props;
postForm(value, schemaName, 1);
}
render() {
const {
schema,
initialValue,
} = this.props;
console.log('props', this.props);
return (
<div>
<h3 id={schema.$id} className={styles.formTitle}>
{schema.title}
</h3>
<Liform
schema={schema}
onSubmit={value => this.handleSubmit(value)}
destroyOnUnmount={false}
theme={theme}
initialValues={initialValue}
/>
</div>
);
}
}
SchemaForm.propTypes = {
schema: PropTypes.shape({
$id: PropTypes.string,
}),
initialValue: PropTypes.object,
schemaName: PropTypes.string,
postForm: PropTypes.func.isRequired,
};
SchemaForm.defaultProps = {
schema: {},
initialValue: null,
schemaName: '',
};
export default SchemaForm;
the schemaNames will be changed only by adding or deleting some element. for example: the schemaNames will change from ['A', 'B', 'C'] to ['A', 'B', 'D']. I get the schemaNames from the redux. which I fetch online.
But when I check the ConnectedReduxForm, when I change the schemaNames, the SchemaForm will be unmounted and the react will mount the form again. I have tried with setting the ConnectedReduxForm to be PureComponent. It is not helpful.
Could someone help me with that? I have spent a lot of time of this and nothing helps.
Update: I have found the problem, the reason of it is that for each time that I for each time I update the workflow, I need to fetch the schemaNames from the server. But I still do not know why this happended. Could someone explain that?