I'm not looking about how to implement an existing hook, but rather to create a new type of hook. Let's say the hook hook_node_load() exists. I want to create something like hook_node_preload(), that fires before the node is loaded.
I've searched and can't seem to find out where in the Drupal code hooks are being fired. I assume it's something like module_invoke_all() or something like that? But I'm not sure where it's called.
Drupal hooks are fired all over the place, throughout all of the Drupal process. There isn't one place that calls all of the hooks.
Below is a list of some of the functions from the Drupal core that create hooks:
http://api.drupal.org/api/drupal/includes%21module.inc/function/calls/module_invoke_all/7
In the case of hook_node_load(), it is called from the entity.inc file located at includes/entity.inc, at line 334.
foreach (module_implements($this->entityInfo['load hook']) as $module) {
call_user_func_array($module . '_' . $this->entityInfo['load hook'], $args);
}
Related
Is there a legit way to check if Posthog has been initialised somewhere in the app?
My NextJS application structure is like that:
_app.tsx -> posthog init inside useEffect
MyComponent-> event capture
My event capture from MyComponent is being initialised before posthog init from _app.tsx and thats why I am not able to record that event. I am just missing those events.
Any hints would be appreciate.
I am also wondering if I place two init functions, one in _app.tsx and one inside MyComponent, would that be a problem?
I would use the same keys and everything. Would I end with two different instances of posthog?
I simulated my Context + DND problem in https://codesandbox.io/s/adoring-booth-33vqo . I have other components which will be added to this example and I will use a Context hook to share values across the page.
After the initial render, everything looks fine. The idea of the list is to change the order within itself and when ones changes the order with drag-drop, it throws an "Invalid Hook" error.
So the (first) real question is, what is triggering this error which is linked to the line
const { lang1Library, updateLang1Library } = useContext(LangContext)
;
Thanks in advance for your help.
Geo
It's not a good approach to provide a link for the whole project even if it is small. But I had a quick look and there's at least one thing you're doing wrong:
// DragEndFct.js
export default function DragEndFct(result, libName) {
const { lang1Library, updateLang1Library } = useContext(LangContext);
This is not React component, but it uses a hook - and it is wrong. Hooks have a special meaning in React and should be used properly (Rules of Hooks).
You can't use hooks inside regular functions and expect them to work. That is why you are getting that error.
So, there are many ways you can try to fix this. For instance, DragEndFct is a regular function, you can declare more arguments and pass stuff you get from context:
// you are using it in components right ?
function DragEndFct(result, libName, param3, param4) {}
// so you probably have access to the context there
// and can pass data from the context when you call it.
// something like this
onDragEnd={function (result) {
console.log();
DragEndFct(result, StaticVars.LANG1_LIBRARY_NAME, lang1Library, updateLang1Library);
}}
You could even make DragEndFct to be a React component - it can just return null (which means no UI will be rendered) but in that case you will have hooks and all other stuff there. It really depends on what you need and how you will use it.
I'm trying to use the second parameter of setState to pass a callback function, but it appears (from what I can gather) that the server-side renderer ignores this parameter completely. I'm using Gatsby which utilizes server-side rendering to build a static React-based site. My call is in an onChange handler, and looks like this:
this.setState({ [event.target.name]: event.target.value }, () => { console.log('setState callback') })
The state is updated as expected, but the callback is never called. Note: The same issue applies whether I pass an object or a function for the first parameter. The component function looks like this:
ReactComponent.prototype.setState = function (partialState, callback) {
[...]
this.updater.enqueueSetState(this, partialState, callback, 'setState');
};
That updater's method, which lives in ReactUpdateQueue.js (according to the call stack) looks like this:
enqueueSetState: function (publicInstance, partialState)
I don't fully understand the build process for React, but I believe that method/file is coming from this file in the source:
/src/renderers/shared/server/ReactPartialRenderer.js
The only other place I can find this function defined is here:
/src/isomorphic/modern/class/ReactNoopUpdateQueue.js
enqueueSetState: function(
publicInstance,
partialState,
callback,
callerName,
) {
warnNoop(publicInstance, 'setState');
}
which looks like the correct method signature, but doesn't appear anywhere in the call stack when I debug the setState call in my code. This doesn't appear to be a problem with client-side rendered React components (I'll try to set up a simple repo to show this issue, but it doesn't appear replicable on CodePen etc.) I know I could use componentDidUpdate to accomplish what I need to do, but the callback is much more convenient in my instance, and I hate leaving a mystery like this unsolved. :)
Well, I figured it out, and turns out, as is too often the case, this was a self-inflicted error. The default Gatsby install uses React v15 but we wanted to use 16, so we added a direct dependency to it in package.json, which got built in to the resulting package. I still don't quite understand why the above mentioned version of enqueueSetState was called instead of the proper one, but removing the reference to react (and adding gatsby-plugin-react-next, which does what we want by simply pointing webpack to the newer version) fixed the issue.
At least this was a good excuse to get a little more familiar with the guts of React. Perhaps this will save somebody else some time in the future.
Using React with React-Router in a project and am wondering if it's possible to limit the possibilities for param names, like so:
www.mydomain.com/books/:id
and allowing 'Catcher in the Rye' and 'To Kill A Mockingbird' to be passed through, like so:
www.mydomain.com/books/catcher-in-the-rye
www.mydomain.com/books/to-kill-a-mocking-bird
I want to say that only a specific set of books can be used in place of :id (just so someone can't type in www.mydomain.com/books/whatever-they-want and have an empty React component render).
I do currently have a '*' route that catches anything not mentioned, but because params are dynamically generated based on whatever is passed, that won't help in this case.
Is this possible? Thanks.
You need to handle this logic in the component. Depending on if this is an already mounted component or not you will need to put the logic in the appropriate function (componentDidMount, componentWillReceiveProps)
if(!(this.props.params.id in myAcceptableParameters)){
redirect to a 404 here
}
I had a problem with tab rendering. The contents of the tabs used to get mixed up as i used the same component on all the tabs and the component had sub-components with id. As the id would appear same on all panels, the components used to get mixed up. I am now using itemId instead of id and the tabs are getting rendered properly.
Now I am facing another problem. Initially I used Ext.getCmp(id) to fetch components in the controller. Now that ids are replaced by itemId, I am using the following:
Ext.getCmp(id).getComponent(itemId);
There is a deep nesting of components in the view and all the intermediate components have itemId. With the above statement, as I go on to fetch deeper components, the statements keeps extending like:
Ext.getCmp(id).getComponent(itemId1).getComponent(itemId2).getComponent(....;
Am I using the statement correctly? Is there a better shorthand method to achieve the purpose?
Please advice.
Basically you using it the right way because a itemId is only unique at component level (at least it has to). But as you might see this will get sort of ugly, therefore I strictly recommend you to use Ext.ComponentQuery or one of it's implementations up() and down() which are both available for most components. Where Ext.ComponentQuery will per default look through the all instantiated components up() and down() will start at the component from which they are executed, only walking through the existing component tree. Also up() and down() always returns the first match where Ext.ComponentQuery always present you a array.
Both accepting the same query string which can be written in various ways (here I recommend you to read the docs)
Here is a example for:
Ext.getCmp(íd).getComponent(itemId1).getComponent(itemId2)
expecting that you are using panels (it can be any component)
Ext.ComponentQuery.query('panel[id=yourId]>panel[itemId=yourId]>panel[itemId=yourId]');
lets say you are using MVC and therefore all your components are custom (have own xtypes). So if you know, that you have only one instance of 'yourcustompanel' with this itemId you may the simply call:
Ext.ComponentQuery.query('yourcustompanel[itemId=yourId]') // note you get always a array
You can use the Ext.ComponentQuery.query(..) or down() or up() to get the component you are referring to.
If you want to get a component(say a button) within a certain component(say within a container) ,you can use
var button = Ext.ComponentQuery.query('button[type=messageButton]', this);
In the above 'this' refers to the container scope.
Or you can use
var button = this.query('button[type=messageButton]');
In the above also 'this' refers to the container scope.
Hope this helps you ..