New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Passing state and methods to custom components #623
Comments
There's nothing stopping you from doing that! You'd just have to pass down a function to the toolbar that updates the state where the events live. |
@tobiasandersen how could I do this? I was under the impression it couldn't be done since we're only passing the class to Thanks in advance! |
you can pass Componets, and functions are valid components (as well as classes)! |
@wasabigeek here's one way to do it: https://codesandbox.io/s/kw645vwm27 @jquense how would you feel about me making an issue template, with a basic codesandbox that people can use for reproducing bugs etc.? |
@tobiasandersen how would you do it with a Class? I've extended the default Toolbar so I can still use the regular methods (e.g. Example below: how could I pass (Apologies in advance for my noobness - I can't seem to find anything on the topic online, probably don't know the right search terms) class CustomToolbar extends Toolbar {
...
render() {
...
return (
<div className='rbc-toolbar'>
<ButtonGroup className="mr-2">
<Button onClick={this.navigate.bind(null, navigate.PREVIOUS)}>
<i className="fa fa-chevron-left"></i>
</Button>
<Button onClick={this.navigate.bind(null, navigate.NEXT)}>
<i className="fa fa-chevron-right"></i>
</Button>
</ButtonGroup>
...
<Button onClick={() => this.props.refreshEvents()}>Refresh Events</Button>
</div>
);
}
}
class Calendar extends React.Component {
constructor(props) {
super(props);
this.state = {
events: [],
}
this.refreshEvents = this.refreshEvents.bind(this);
}
refreshEvents() {
...
this.setState({events: events});
}
handleNavigate(date, view, action) {
this.refreshEvents();
}
render() {
return (
<BigCalendar
events={this.state.events}
views={['month', 'week']}
components={{toolbar: CustomToolbar}}
onNavigate={this.handleNavigate}
/>
);
}
} |
Ok this seems to work for me, encapsulate the class in another function: const CustomToolbar = ({refreshEvents}) => {
return class BaseToolbar extends Toolbar { ... }
}
class Calendar extends React.Component {
...
render() {
return (
<BigCalendar
...
components={{toolbar: CustomToolbar({this.refreshEvents})}}
/>
);
}
} If there's a better way to do it I'd love to know - otherwise, thanks for the example! |
Hello, i tried to use custom toolba as you showed before, but I get this warning:
Tried to search everywhere for this problem, but i couldn't find anything to help me. I've tried to add 'onView' prop to BigCalendar component, but it doesn't work. `const CustomToolbar = (courses) => {
};` |
@DresDasLT could you edit to include |
`<BigCalendar
|
There is one problem, i dont' use |
@wasabigeek Can you post a link to your full imports for your example? I am only trying to create a custom toolbar and can't access the original methods, eg this.navigate? I'm also using typescript so I really could use a working example in jsx? |
@GavinThomas1192 sorry for the late response, this is my import statement If you don't want to do class inheritance (which admittedly, is not recommended in React), I suggest using the source as a base (i.e. copy it and edit): https://github.com/intljusticemission/react-big-calendar/blob/master/src/Toolbar.js. |
Hey @wasabigeek , thanks for getting back to me! I am using typescript and the issue was that their types were incorrect and I was calling this.props.navigate(date, PREV) and it should have been reversed. Heres my custom header for reference, since this single post was super important for myself when trying to create a custom header.
{label}
} |
Hi @wasabigeek, this answer is long time closed but i still cannot figure the syntax to pass the prop to my imported custom class component. import React, {Component} from 'react'
import Calendar from 'react-big-calendar'
// my External custom components
import CustomToolbar from './components/CustomToolbar'
class App extends Component {
// encapsulating the class component, not sure if ok
CustomToolbarCapsule = (something) => {
const instance = new CustomToolbar(something)
return instance.render()
}
render() {
const something = this.state.something
const components = {
toolbar: this.CustomToolbarCapsule({something})
}
return (<Calendar components={components} />)
} |
For future reference, I ended up doing this, but I really don't think it's the right way. import React, {Component} from 'react'
import Calendar from 'react-big-calendar'
// my external custom components
import CustomToolbar from './components/CustomToolbar'
class App extends Component {
// encapsulating the class component, not sure if ok
CustomToolbarCapsule = (props) => {
return class CustomToolbarInstance extends CustomToolbar {
static defaultProps = { ...props }
}
}
render() {
const something = this.state.something
const components = {
toolbar: this.CustomToolbarCapsule({something})
}
return (<Calendar components={components} />)
} If anybody could advise for a better solution, please let me know. |
@elgandoz I don't really know the terminology or the best practices, but if you look at https://github.com/intljusticemission/react-big-calendar/blob/master/src/Calendar.js#L888 you'll see that the custom toolbar is declared in In your first example, when you declare There are other ways you can declare it, e.g. in your first example you should be able to keep everything the same and wrap the custom component in an anonymous function: const components = {
toolbar: () => this.CustomToolbarCapsule({something})
} Hope that helps! |
Thanks for the reply @wasabigeek. I tried your solution but I get the error: That's because all the default props of my custom toolbar gets replaced by <CustomToolbar someprop={something} /> The problem is that I cannot use that syntax when declaring the calendar components, and if my class is in a different file ( Below you can find a snipper of what's going on in the // CustomToolbar.js, imported in App.js
import React from 'react'
import Toolbar from 'react-big-calendar/lib/Toolbar'
class CustomToolbar extends Toolbar {
render() {
// someprops is custom, the others are default passed by BigCalendar
const { someprop, onNavigate, label , localizer: { messages } } = this.props
[...]
}
} In the end, all I want is to pass a prop to an imported class component. My last example with |
@elgandoz, since the de-structuring of I realise we missed passing the props down to the custom toolbar, that could be the reason (I think this would be the syntax): |
@wasabigeek That could work, but how do I get the default props passed to the toolbar (or to any custom component)? |
This issue shouldn't be closed. The problem is as @elgandoz says, the props passed to Custom components this way are overwriting existing components props. Is there a way to keep them both? |
I want to get answer to @mdjuric-itk question too. |
I had a similar problem and i fixed it by using a function when adding my custom component
This will allow you to keep the default props and add your own custom props |
Guys all your suggestions neglect the fact that it WONT RE-RENDER if the props change. This is bad practice and I am puzzled without they haven't fixed it yet. |
After hours of scouring all these git issues and PRs, this was the only thing that worked for me. This also allowed me to pass functions as props as well, which is the main thing I was trying to do. |
@pitops have you found a solution for this? |
The best way of handling accessing custom props and methods from within an override component is by using context. Here's an example of how to accomplish this. |
It's great that we can specify our own custom components, but they seem to be Uncontrolled. I would like to be able to pass state and methods down to custom components - is there a way to do this?
An example use case - I want to add a button in the Toolbar which will modify some of the events on the calendar.
The text was updated successfully, but these errors were encountered: