I have not been using ReactJS for very long. I have a situation that I think must be very common, but I’ve not seen it addressed in any examples, and I’d like to know if there are any best practices involved.
The scenario is simply that say I have 3 forms in my application, FormA, FormB, and FormC. I have written each form as a separate ReactJS component. When the user lands on the site, FormA is displayed. Depending on the input on FormA, then either FormB or FormC will be displayed next, completely replacing FormA on the page.
I don’t think “routing” is the answer because I don’t want the URL to reflect the current application state, and I don’t want the user to be able to change forms by changing the URL. The switching of forms (components) should be done based only on business rules.
I know ReactJS is not a framework, but this seems like a common enough scenario that some useful patterns have probably evolved around it. Just a nudge in the right direction would be very helpful. Thank you.
The View is the fundamental component of React Native for building a user interface. It is a container that supports layout with flexbox, style, touch handling, and accessibility controls. It maps directly to the native view similar to whatever platform on React Native app is running on.
The window object is the normal DOM object. It is always available and safe to use (unless you are server side rendering).
A component cannot update its own props unless they are arrays or objects (having a component update its own props even if possible is an anti-pattern), but can update its state and the props of its children.
The shouldComponentUpdate is a lifecycle method in React. This method makes the component to re-render only when there is a change in state or props of a component and that change will affect the output.
The solution is to create wrapper Form
component that contains FormA
, FormB
, FormC
and show one of them depends on its state. Like
const Form = React.createComponent({
getInitialState() {
return {
form: 'formA'
/* other state */
}
},
render() {
return (
<div>
{this.state.form === 'formA' ? <FormA onSubmit={this.saveFormData} /> : null}
{this.state.form === 'formB' ? <FormB onSubmit={this.saveFormData} /> : null}
{this.state.form === 'formC' ? <FormC onSubmit={this.saveFormData} /> : null}
</div>
)
},
saveFromData() {
/* set state here */
}
})
Such delegation is common for React. Normally you should manage your forms logic in the Form
and FormA
, FormB
, FormC
should be dumb components that can only execute functions from passed props.
Note that example code listing above is just a demonstration. Usually you don't need to keep form
in state. Instead there can be i. e. username
, password
, email
(or anything) and you should check what form to show based on this state values.
Here's a very simple solution creating a SwitchComponents
component:
// SwitchComponents.js:
import React from 'react';
export default function SwitchComponents({ active, children }) {
// Switch all children and return the "active" one
return children.filter(child => child.props.name == active)
}
And import it in your app:
// App.js
import SwitchComponents from './components/SwitchComponents';
export default function App() {
const [activeComponent, setActiveComponent] = useState("questions")
return (
<SwitchComponents active={activeComponent}>
<Home name="home" />
<Instructions name="instructions" />
<FileboxContainer name="filebox" />
<Questions name="questions" />
</SwitchComponents>
)
}
If you don't wanna pass the "name" property, you can you the solution below:
return children.filter(child => child.type.name == active)
But that's the name you give to your function when you define you component, like this:
export default function MyFunctionName() { ... } // this is the name
Even if you import it with another name, that's still gonna be the name you must use.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With