score:0
You already have everything you need in order to accomplish that. Maybe just change the line where you render PostForm
and accept props.children
coming from your new component. With that you will be able to render any form you want inside of it.
Remember that the less business logic you keep outside of FormHandler
the better. Each form should be aware of what to do on every field change or on submit.
For example, this.createPost
should not be part of FormHandler
in case you want to reuse it throughout your code.
class FormHandler extends React.Component {
constructor(props) {
super(props)
this.state = {
formOpen: false,
}
this.toggleFormOpen = this.toggleFormOpen.bind(this)
}
toggleFormOpen() {
this.setState({
formOpen: !this.state.formOpen,
})
}
render() {
return (
<div>
<button onClick={this.toggleFormOpen}>
{this.state.formOpen ? 'Close' : 'Open'}
</button>
{this.state.formOpen && React.cloneElement(
this.props.children,
{
onClose: this.toggleFormOpen
}
)}
</div>
)
}
}
const PostForm = ({ onClose, onSubmit }) =>
<form>
<input type="text" placeholder="Post Name" />
<input type="text" placeholder="Post Title" />
<input type="text" placeholder="Date" />
<button onClick={event => {
event.preventDefault()
onSubmit({ postName: '', postTitle: '', date: ''})
onClose()
}}>
Submit
</button>
</form>
const UserForm = ({ onClose, onSubmit }) =>
<form>
<input type="text" placeholder="First Name" />
<input type="text" placeholder="Last Name" />
<button onClick={event => {
event.preventDefault()
onSubmit({ firstName: '', lastName: '' })
onClose()
}}>
Submit
</button>
</form>
const App = () =>
<div>
<FormHandler>
<PostForm
onSubmit={formData => console.log('PostForm', formData)}
/>
</FormHandler>
<br />
<FormHandler>
<UserForm
onSubmit={formData => console.log('UserForm', formData)}
/>
</FormHandler>
</div>
ReactDOM.render(
<App />,
document.getElementById('root')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root"></div>
score:1
I will go about it by making a factory that returns a React Component, than render the children as props
const FormHandlerFactory = ({Form = PostForm}) => {
return class FormHandler extends React.Component {
render() {
return (
<div>
{this.state.editFormOpen?
<div>
<Link
to=''
onClick={()=>{this.setState({editFormOpen:false})}}>
Close
</Link>
<Form
onSubmit={(post)=>this.createPost(post)}
/>
</div>:
<Link
to=''
onClick={()=>{this.setState({editFormOpen:true})}}>
Add post
</Link>}
</div>
)
}
}
}
You can use this factory as
const FormHandler = FormHandlerFactory({Form: YourCustomFormComponent});
const App = (props) => (
<Form {...props}
)
score:1
You could create a stateless component that could render any children that you passed in that component you also need to put the states in the parent component
const ToggleForm = ({ editFormOpen, editFormHandler, children }) => (
<div>
{editFormOpen?
<div>
<Link
to=''
onClick={() => editFormHandler(false)}>
Close
</Link>
{children}
</div>:
<Link
to=''
onClick={() => editFormHandler(true)}>
Add post
</Link>}
</div>
);
class ParentCmp extends React.Component {
constructor(props) {
super(props);
this.state = {
editFormOpen: false,
}
this.editFormHandler = this.editFormHandler.bind(this);
this.createPost = this.createPost.bind(this);
}
editFormHandler(boolValue) {
this.setState({
editFormOpen: boolValue
});
}
render() {
return (
<div>
<ToggleForm
editFormOpen={this.state.editFormOpen}
editFormHandler={this.state.editFormHandler}
>
<PostForm
onSubmit={(post)=>this.createPost(post)}
/>
</ToggleForm>
</div>
)
}
}
Source: stackoverflow.com
Related Query
- Developing a generic React component to open and close arbitrary forms
- Dynamically Open and Close antd / react Collapse Component
- Why memory leak happend and render slowing down when I close and re-open react component (material-table)?
- Open menu on mouseover and Close menu on mouseleave in react
- Open and Close a recursively nested list in React js
- Use Generic flow types in React component Props and instantiate generic component>
- react Portal - how to close modal when clicking outside of modal and how to assign ref to modal inside parent component rendering modal?
- Handle a custom component using React Hook Forms and React Table
- React Component Open and Collapse Animation with dynamic content
- Typescript React component with function overload and generic params
- React and Typescript: How to extend generic component props?
- React component modal is open at load and never closes
- How to generically type React component props and extend the generic props type
- State to open and close a Dialog in TypeScript in React
- How to open and and close a small window in react passport auth flow
- Embed custom form twice, one instance open and another is close with React js?
- Typescript: Type representing a generic React component or HTML element, and its props
- Pass child state to parent to open and close menu component
- Will the background component unmount when modal is open in react? If not, how to maintain/store states of modal and react component using redux?
- How to open and close an inline dialog in a react redux app
- React Component and Typescript - Generic Props
- How to be able to open the file explorer in a class component and read the selected file in React JS
- React Toggle open and close using onclick on map function
- Difference between component and container in react redux
- React - animate mount and unmount of a single component
- Difference between React Component and React Element
- react router difference between component and render
- Difference between import React and import { Component } syntax
- How to mock React component methods with jest and enzyme
- How do I wrap a React component that returns multiple table rows and avoid the "<tr> cannot appear as a child of <div>" error?
More Query from same tag
- How to set local storage in cypress
- Best way to handle component loading in react
- How can I redirect to another component in react and pass the state that I set in the previous component?
- How to create word in and out animation
- Validating URL Parameters in React Router v4
- React Redux how to update a object from array
- How to map my firestore collection documents into a table
- Concat runs twice but if statement only run once and console show going in once only
- Dynamically imported component is treated as JSX element
- How to use loops in promises
- stop use eventsource being resubscribed to in react app
- React + TS + hooks problem at action dispatch
- test listItem using jest
- React/MobX component not re-rendering after state change (found a weird solution, would like to know why)
- How do you get the user db details related to an authUser in Firestore?
- Intital route name parameter for React navigation app drawer (React Native)
- Custom color theme not working correctly on Bootstrap, React, SCSS project
- react-router routes not giving the desired output when rendered not showing anything on the webpage
- ReactJS form validation
- Deleting an item from a collection in f, using React Redux
- Consume RESTful data with React and Axios
- Handling with external logouts in React app
- Runtime error appeared after updating to webpack 5. TypeError: Cannot read properties of undefined (reading 'default')
- Electron.js and webpack with Creact-react-app
- How to replicate the nextjs getStaticProps() function for all pages without having to repeat all pages
- cfs collection showing error in react.component
- How to Set Style to image pattern on mapbox GL
- react table sort not working on calculated column
- Authenticate user in spring boot with react login form
- Not working Server side rendering Styled-Components with Next JS